1 package org.apache.torque.manager; 2 3 21 22 import java.lang.ref.WeakReference ; 23 import java.util.Arrays ; 24 import java.util.List ; 25 import java.util.ArrayList ; 26 import java.util.Map ; 27 import java.util.HashMap ; 28 import java.util.Iterator ; 29 import java.io.Serializable ; 30 import java.io.IOException ; 31 import java.io.ObjectInputStream ; 32 33 import org.apache.commons.collections.FastArrayList; 34 import org.apache.jcs.JCS; 35 import org.apache.jcs.access.GroupCacheAccess; 36 import org.apache.jcs.access.exception.CacheException; 37 38 import org.apache.torque.Torque; 39 import org.apache.torque.TorqueException; 40 import org.apache.torque.om.ObjectKey; 41 import org.apache.torque.om.Persistent; 42 43 import org.apache.commons.logging.Log; 44 import org.apache.commons.logging.LogFactory; 45 46 53 public abstract class AbstractBaseManager 54 implements Serializable 55 { 56 57 protected static final Log log = LogFactory.getLog(AbstractBaseManager.class); 58 59 60 protected transient GroupCacheAccess cache; 61 62 63 protected MethodResultCache mrCache; 64 65 66 private Class omClass; 67 68 private String className; 69 70 private String region; 71 72 private boolean isNew = true; 73 74 protected Map validFields; 75 protected Map listenersMap = new HashMap (); 76 77 82 protected Class getOMClass() 83 { 84 return omClass; 85 } 86 87 92 protected void setOMClass(Class omClass) 93 { 94 this.omClass = omClass; 95 } 96 97 104 protected Persistent getOMInstance() 105 throws InstantiationException , IllegalAccessException 106 { 107 return (Persistent) omClass.newInstance(); 108 } 109 110 114 public String getClassName() 115 { 116 return className; 117 } 118 119 125 public void setClassName(String v) 126 throws TorqueException 127 { 128 this.className = v; 129 130 try 131 { 132 setOMClass(Class.forName(getClassName())); 133 } 134 catch (ClassNotFoundException cnfe) 135 { 136 throw new TorqueException("Could not load " + getClassName()); 137 } 138 } 139 140 141 149 protected Persistent getOMInstance(ObjectKey id) 150 throws TorqueException 151 { 152 return getOMInstance(id, true); 153 } 154 155 164 protected Persistent getOMInstance(ObjectKey key, boolean fromCache) 165 throws TorqueException 166 { 167 Persistent om = null; 168 if (fromCache) 169 { 170 om = cacheGet(key); 171 } 172 173 if (om == null) 174 { 175 om = retrieveStoredOM(key); 176 if (fromCache) 177 { 178 putInstanceImpl(om); 179 } 180 } 181 182 return om; 183 } 184 185 191 protected Persistent cacheGet(Serializable key) 192 { 193 Persistent om = null; 194 if (cache != null) 195 { 196 synchronized (this) 197 { 198 om = (Persistent) cache.get(key); 199 } 200 } 201 return om; 202 } 203 204 210 protected void clearImpl() 211 throws TorqueException 212 { 213 if (cache != null) 214 { 215 try 216 { 217 cache.remove(); 218 } 219 catch (CacheException ce) 220 { 221 throw new TorqueException( 222 "Could not clear cache due to internal JCS error.", ce); 223 } 224 } 225 } 226 227 235 protected Persistent removeInstanceImpl(Serializable key) 236 throws TorqueException 237 { 238 Persistent oldOm = null; 239 if (cache != null) 240 { 241 try 242 { 243 synchronized (this) 244 { 245 oldOm = (Persistent) cache.get(key); 246 cache.remove(key); 247 } 248 } 249 catch (CacheException ce) 250 { 251 throw new TorqueException 252 ("Could not remove from cache due to internal JCS error", 253 ce); 254 } 255 } 256 return oldOm; 257 } 258 259 268 protected Persistent putInstanceImpl(Persistent om) 269 throws TorqueException 270 { 271 ObjectKey key = om.getPrimaryKey(); 272 return putInstanceImpl(key, om); 273 } 274 275 285 protected Persistent putInstanceImpl(Serializable key, Persistent om) 286 throws TorqueException 287 { 288 if (getOMClass() != null && !getOMClass().isInstance(om)) 289 { 290 throw new TorqueException(om + "; class=" + om.getClass().getName() 291 + "; id=" + om.getPrimaryKey() + " cannot be cached with " 292 + getOMClass().getName() + " objects"); 293 } 294 295 Persistent oldOm = null; 296 if (cache != null) 297 { 298 try 299 { 300 synchronized (this) 301 { 302 oldOm = (Persistent) cache.get(key); 303 cache.put(key, om); 304 } 305 } 306 catch (CacheException ce) 307 { 308 throw new TorqueException 309 ("Could not cache due to internal JCS error", ce); 310 } 311 } 312 return oldOm; 313 } 314 315 323 protected abstract Persistent retrieveStoredOM(ObjectKey id) 324 throws TorqueException; 325 326 334 protected List getOMs(ObjectKey[] ids) 335 throws TorqueException 336 { 337 return getOMs(Arrays.asList(ids)); 338 } 339 340 348 protected List getOMs(List ids) 349 throws TorqueException 350 { 351 return getOMs(ids, true); 352 } 353 354 362 protected List getOMs(List ids, boolean fromCache) 363 throws TorqueException 364 { 365 List oms = null; 366 if (ids != null && ids.size() > 0) 367 { 368 oms = new ArrayList (ids); 370 List newIds = new ArrayList (ids.size()); 371 for (int i = 0; i < ids.size(); i++) 372 { 373 ObjectKey key = (ObjectKey) ids.get(i); 374 Persistent om = null; 375 if (fromCache) 376 { 377 om = cacheGet(key); 378 } 379 if (om == null) 380 { 381 newIds.add(key); 382 } 383 else 384 { 385 oms.set(i, om); 386 } 387 } 388 389 if (newIds.size() > 0) 390 { 391 List newOms = retrieveStoredOMs(newIds); 392 for (int i = 0; i < oms.size(); i++) 393 { 394 if (oms.get(i) instanceof ObjectKey) 395 { 396 for (int j = newOms.size() - 1; j >= 0; j--) 397 { 398 Persistent om = (Persistent) newOms.get(j); 399 if (om.getPrimaryKey().equals(oms.get(i))) 400 { 401 oms.set(i, om); 404 newOms.remove(j); 405 if (fromCache) 406 { 407 putInstanceImpl(om); 408 } 409 break; 410 } 411 } 412 } 413 } 414 } 415 } 416 return oms; 417 } 418 419 428 protected abstract List retrieveStoredOMs(List ids) 429 throws TorqueException; 430 431 436 public String getRegion() 437 { 438 return region; 439 } 440 441 448 public void setRegion(String v) 449 throws TorqueException 450 { 451 this.region = v; 452 try 453 { 454 if (Torque.getConfiguration().getBoolean(Torque.CACHE_KEY, false)) 455 { 456 cache = JCS.getInstance(getRegion()); 457 mrCache = new MethodResultCache(cache); 458 } 459 else 460 { 461 mrCache = new NoOpMethodResultCache(cache); 462 } 463 } 464 catch (CacheException e) 465 { 466 throw new TorqueException("Cache could not be initialized", e); 467 } 468 469 if (cache == null) 470 { 471 log.info("Cache could not be initialized for region: " + v); 472 } 473 } 474 475 478 public MethodResultCache getMethodResultCache() 479 { 480 if (isNew) 481 { 482 synchronized (this) 483 { 484 if (isNew) 485 { 486 registerAsListener(); 487 isNew = false; 488 } 489 } 490 } 491 return mrCache; 492 } 493 494 498 protected void registerAsListener() 499 { 500 } 501 502 506 public void addCacheListenerImpl(CacheListener listener) 507 { 508 List keys = listener.getInterestedFields(); 509 Iterator i = keys.iterator(); 510 while (i.hasNext()) 511 { 512 String key = (String ) i.next(); 513 if (validFields != null && validFields.containsKey(key)) 515 { 516 List listeners = (List ) listenersMap.get(key); 517 if (listeners == null) 518 { 519 listeners = createSubsetList(key); 520 } 521 522 boolean isNew = true; 523 Iterator j = listeners.iterator(); 524 while (j.hasNext()) 525 { 526 Object listener2 = 527 ((WeakReference ) j.next()).get(); 528 if (listener2 == null) 529 { 530 } 535 else if (listener2 == listener) 536 { 537 isNew = false; 538 break; 539 } 540 } 541 if (isNew) 542 { 543 listeners.add(new WeakReference (listener)); 544 } 545 } 546 } 547 } 548 549 554 private synchronized List createSubsetList(String key) 555 { 556 FastArrayList list = null; 557 if (listenersMap.containsKey(key)) 558 { 559 list = (FastArrayList) listenersMap.get(key); 560 } 561 else 562 { 563 list = new FastArrayList(); 564 list.setFast(true); 565 listenersMap.put(key, list); 566 } 567 return list; 568 } 569 570 576 protected void notifyListeners(List listeners, 577 Persistent oldOm, Persistent om) 578 { 579 if (listeners != null) 580 { 581 synchronized (listeners) 582 { 583 Iterator i = listeners.iterator(); 584 while (i.hasNext()) 585 { 586 CacheListener listener = (CacheListener) 587 ((WeakReference ) i.next()).get(); 588 if (listener == null) 589 { 590 i.remove(); 592 } 593 else 594 { 595 if (oldOm == null) 596 { 597 listener.addedObject(om); 599 } 600 else 601 { 602 listener.refreshedObject(om); 604 } 605 } 606 } 607 } 608 } 609 } 610 611 612 618 private void writeObject(java.io.ObjectOutputStream out) 619 throws IOException 620 { 621 out.defaultWriteObject(); 622 } 623 624 631 private void readObject(ObjectInputStream in) 632 throws IOException , ClassNotFoundException 633 { 634 in.defaultReadObject(); 635 try 637 { 638 if (region != null) 639 { 640 setRegion(region); 641 } 642 } 643 catch (Exception e) 644 { 645 log.error("Cache could not be initialized for region '" 646 + region + "' after deserialization"); 647 } 648 } 649 } 650 | Popular Tags |