1 package org.apache.turbine.services.pool; 2 3 18 19 import java.lang.reflect.Method ; 20 21 import java.util.ArrayList ; 22 import java.util.HashMap ; 23 import java.util.Iterator ; 24 25 import org.apache.commons.configuration.Configuration; 26 27 import org.apache.commons.logging.Log; 28 import org.apache.commons.logging.LogFactory; 29 30 import org.apache.turbine.services.InitializationException; 31 import org.apache.turbine.services.TurbineBaseService; 32 import org.apache.turbine.services.factory.FactoryService; 33 import org.apache.turbine.services.factory.TurbineFactory; 34 import org.apache.turbine.util.TurbineException; 35 import org.apache.turbine.util.pool.ArrayCtorRecyclable; 36 import org.apache.turbine.util.pool.BoundedBuffer; 37 import org.apache.turbine.util.pool.Recyclable; 38 39 54 public class TurbinePoolService 55 extends TurbineBaseService 56 implements PoolService 57 { 58 59 private boolean debugPool = false; 60 61 62 private FactoryService factoryService; 63 64 65 private static Log log = LogFactory.getLog(TurbinePoolService.class); 66 67 70 private class PoolBuffer 71 { 72 75 private class Recycler 76 { 77 78 private final Method recycle; 79 80 81 private final String [] signature; 82 83 89 public Recycler(Method rec, String [] sign) 90 { 91 recycle = rec; 92 signature = ((sign != null) && (sign.length > 0)) 93 ? sign : null; 94 } 95 96 103 public Method match(String [] sign) 104 { 105 if ((sign != null) && (sign.length > 0)) 106 { 107 if ((signature != null) 108 && (sign.length == signature.length)) 109 { 110 for (int i = 0; i < signature.length; i++) 111 { 112 if (!signature[i].equals(sign[i])) 113 { 114 return null; 115 } 116 } 117 return recycle; 118 } 119 else 120 { 121 return null; 122 } 123 } 124 else if (signature == null) 125 { 126 return recycle; 127 } 128 else 129 { 130 return null; 131 } 132 } 133 } 134 135 136 private BoundedBuffer pool; 137 138 139 private boolean arrayCtorRecyclable; 140 141 142 private ArrayList recyclers; 143 144 149 public PoolBuffer(int capacity) 150 { 151 pool = new BoundedBuffer(capacity); 152 } 153 154 160 public void setArrayCtorRecyclable(boolean isArrayCtor) 161 { 162 arrayCtorRecyclable = isArrayCtor; 163 } 164 165 170 public Object poll(Object [] params, String [] signature) 171 throws TurbineException 172 { 173 if (debugPool && (pool.size() < (pool.capacity() / 2))) 177 { 178 log.debug("Size: " + pool.size() 179 + ", capacity: " + pool.capacity()); 180 return null; 181 } 182 183 Object instance = pool.poll(); 184 if (instance != null) 185 { 186 if (arrayCtorRecyclable) 187 { 188 ((ArrayCtorRecyclable) instance).recycle(params); 189 } 190 else if (instance instanceof Recyclable) 191 { 192 try 193 { 194 if ((signature != null) && (signature.length > 0)) 195 { 196 197 Method recycle = getRecycle(signature); 198 if (recycle == null) 199 { 200 synchronized (this) 201 { 202 203 recycle = getRecycle(signature); 204 if (recycle == null) 205 { 206 Class clazz = instance.getClass(); 207 recycle = clazz.getMethod("recycle", 208 factoryService.getSignature( 209 clazz, params, signature)); 210 ArrayList cache = recyclers != null 211 ? (ArrayList ) recyclers.clone() 212 : new ArrayList (); 213 cache.add( 214 new Recycler(recycle, signature)); 215 recyclers = cache; 216 } 217 } 218 } 219 recycle.invoke(instance, params); 220 } 221 else 222 { 223 ((Recyclable) instance).recycle(); 224 } 225 } 226 catch (Exception x) 227 { 228 throw new TurbineException( 229 "Recycling failed for " + instance.getClass().getName(), x); 230 } 231 } 232 } 233 return instance; 234 } 235 236 241 public boolean offer(Object instance) 242 { 243 if (instance instanceof Recyclable) 244 { 245 try 246 { 247 ((Recyclable) instance).dispose(); 248 } 249 catch (Exception x) 250 { 251 return false; 252 } 253 } 254 return pool.offer(instance); 255 } 256 257 262 public int capacity() 263 { 264 return pool.capacity(); 265 } 266 267 272 public int size() 273 { 274 return pool.size(); 275 } 276 277 284 private Method getRecycle(String [] signature) 285 { 286 ArrayList cache = recyclers; 287 if (cache != null) 288 { 289 Method recycle; 290 for (Iterator i = cache.iterator(); i.hasNext();) 291 { 292 recycle = ((Recycler) i.next()).match(signature); 293 if (recycle != null) 294 { 295 return recycle; 296 } 297 } 298 } 299 return null; 300 } 301 } 302 303 306 private int poolCapacity = DEFAULT_POOL_CAPACITY; 307 308 311 private HashMap poolRepository = new HashMap (); 312 313 316 public TurbinePoolService() 317 { 318 } 319 320 326 public void init() 327 throws InitializationException 328 { 329 Configuration conf = getConfiguration(); 330 331 int capacity = conf.getInt(POOL_CAPACITY_KEY, 332 DEFAULT_POOL_CAPACITY); 333 334 if (capacity <= 0) 335 { 336 throw new IllegalArgumentException ("Capacity must be >0"); 337 } 338 poolCapacity = capacity; 339 340 debugPool = conf.getBoolean(POOL_DEBUG_KEY, 341 POOL_DEBUG_DEFAULT); 342 343 if (debugPool) 344 { 345 log.info("Activated Pool Debugging!"); 346 } 347 348 factoryService = TurbineFactory.getService(); 349 350 if (factoryService == null) 351 { 352 throw new InitializationException("Factory Service is not configured" 353 + " but required for the Pool Service!"); 354 } 355 356 setInit(true); 357 } 358 359 367 public Object getInstance(String className) 368 throws TurbineException 369 { 370 Object instance = pollInstance(className, null, null); 371 return (instance == null) 372 ? factoryService.getInstance(className) 373 : instance; 374 } 375 376 386 public Object getInstance(String className, 387 ClassLoader loader) 388 throws TurbineException 389 { 390 Object instance = pollInstance(className, null, null); 391 return (instance == null) 392 ? factoryService.getInstance(className, loader) 393 : instance; 394 } 395 396 409 public Object getInstance(String className, 410 Object [] params, 411 String [] signature) 412 throws TurbineException 413 { 414 Object instance = pollInstance(className, params, signature); 415 return (instance == null) 416 ? factoryService.getInstance(className, params, signature) 417 : instance; 418 } 419 420 434 public Object getInstance(String className, 435 ClassLoader loader, 436 Object [] params, 437 String [] signature) 438 throws TurbineException 439 { 440 Object instance = pollInstance(className, params, signature); 441 return (instance == null) 442 ? factoryService.getInstance(className, loader, params, signature) 443 : instance; 444 } 445 446 454 public boolean isLoaderSupported(String className) 455 throws TurbineException 456 { 457 return factoryService.isLoaderSupported(className); 458 } 459 460 468 public Object getInstance(Class clazz) 469 throws TurbineException 470 { 471 Object instance = pollInstance(clazz.getName(), null, null); 472 return (instance == null) 473 ? factoryService.getInstance(clazz.getName()) 474 : instance; 475 } 476 477 487 public Object getInstance(Class clazz, 488 Object params[], 489 String signature[]) 490 throws TurbineException 491 { 492 Object instance = pollInstance(clazz.getName(), params, signature); 493 return (instance == null) 494 ? factoryService.getInstance(clazz.getName(), params, signature) 495 : instance; 496 } 497 498 507 public boolean putInstance(Object instance) 508 { 509 if (instance != null) 510 { 511 HashMap repository = poolRepository; 512 String className = instance.getClass().getName(); 513 PoolBuffer pool = (PoolBuffer) repository.get(className); 514 if (pool == null) 515 { 516 pool = new PoolBuffer(getCapacity(className)); 517 repository = (HashMap ) repository.clone(); 518 repository.put(className, pool); 519 poolRepository = repository; 520 521 if (instance instanceof ArrayCtorRecyclable) 522 { 523 pool.setArrayCtorRecyclable(true); 524 } 525 } 526 return pool.offer(instance); 527 } 528 else 529 { 530 return false; 531 } 532 } 533 534 539 public int getCapacity(String className) 540 { 541 PoolBuffer pool = (PoolBuffer) poolRepository.get(className); 542 if (pool == null) 543 { 544 545 int capacity; 546 547 Configuration conf = getConfiguration(); 548 capacity = conf.getInt( 549 POOL_CAPACITY_KEY + '.' + className, 550 poolCapacity); 551 capacity = (capacity <= 0) ? poolCapacity : capacity; 552 return capacity; 553 } 554 else 555 { 556 return pool.capacity(); 557 } 558 } 559 560 567 public void setCapacity(String className, 568 int capacity) 569 { 570 HashMap repository = poolRepository; 571 repository = (repository != null) 572 ? (HashMap ) repository.clone() : new HashMap (); 573 574 capacity = (capacity <= 0) ? poolCapacity : capacity; 575 576 repository.put(className, new PoolBuffer(capacity)); 577 poolRepository = repository; 578 } 579 580 585 public int getSize(String className) 586 { 587 PoolBuffer pool = (PoolBuffer) poolRepository.get(className); 588 return (pool != null) ? pool.size() : 0; 589 } 590 591 596 public void clearPool(String className) 597 { 598 HashMap repository = poolRepository; 599 if (repository.get(className) != null) 600 { 601 repository = (HashMap ) repository.clone(); 602 repository.remove(className); 603 poolRepository = repository; 604 } 605 } 606 607 610 public void clearPool() 611 { 612 poolRepository = new HashMap (); 613 } 614 615 624 private Object pollInstance(String className, 625 Object [] params, 626 String [] signature) 627 throws TurbineException 628 { 629 PoolBuffer pool = (PoolBuffer) poolRepository.get(className); 630 return (pool != null) ? pool.poll(params, signature) : null; 631 } 632 } 633 | Popular Tags |