1 package org.apache.ojb.broker.core.proxy; 2 3 17 18 import java.lang.reflect.Method ; 19 import java.util.ArrayList ; 20 21 import org.apache.ojb.broker.Identity; 22 import org.apache.ojb.broker.OJBRuntimeException; 23 import org.apache.ojb.broker.PBFactoryException; 24 import org.apache.ojb.broker.PBKey; 25 import org.apache.ojb.broker.PersistenceBrokerException; 26 import org.apache.ojb.broker.PersistenceBrokerFactory; 27 import org.apache.ojb.broker.PersistenceBrokerInternal; 28 import org.apache.ojb.broker.core.PersistenceBrokerThreadMapping; 29 import org.apache.ojb.broker.util.logging.LoggerFactory; 30 31 36 public abstract class AbstractIndirectionHandler implements IndirectionHandler 37 { 38 static final long serialVersionUID = -1993879565033755826L; 39 40 41 private PBKey _brokerKey; 42 43 private Object _realSubject = null; 44 46 private Identity _id = null; 47 48 private transient ArrayList _listeners; 49 50 58 public AbstractIndirectionHandler(PBKey brokerKey, Identity id) 59 { 60 setBrokerKey(brokerKey); 61 setIdentity(id); 62 } 63 64 69 public Identity getIdentity() 70 { 71 return _id; 72 } 73 74 79 protected void setIdentity(Identity identity) 80 { 81 _id = identity; 82 } 83 84 90 public PBKey getBrokerKey() 91 { 92 return _brokerKey; 93 } 94 95 101 protected void setBrokerKey(PBKey brokerKey) 102 { 103 _brokerKey = brokerKey; 104 } 105 106 112 public synchronized void addListener(MaterializationListener listener) 113 { 114 if (_listeners == null) 115 { 116 _listeners = new ArrayList (); 117 } 118 if (!_listeners.contains(listener)) 120 { 121 _listeners.add(listener); 122 } 123 } 124 125 131 public synchronized void removeListener(MaterializationListener listener) 132 { 133 if (_listeners != null) 134 { 135 _listeners.remove(listener); 136 } 137 } 138 139 143 protected void beforeMaterialization() 144 { 145 if (_listeners != null) 146 { 147 MaterializationListener listener; 148 149 for (int idx = _listeners.size() - 1; idx >= 0; idx--) 150 { 151 listener = (MaterializationListener) _listeners.get(idx); 152 listener.beforeMaterialization(this, _id); 153 } 154 } 155 } 156 157 161 protected void afterMaterialization() 162 { 163 if (_listeners != null) 164 { 165 MaterializationListener listener; 166 167 for (int idx = _listeners.size() - 1; idx >= 0; idx--) 173 { 174 listener = (MaterializationListener) _listeners.get(idx); 175 listener.afterMaterialization(this, _realSubject); 176 } 177 } 178 } 179 180 186 protected TemporaryBrokerWrapper getBroker() throws PBFactoryException 187 { 188 PersistenceBrokerInternal broker; 189 boolean needsClose = false; 190 191 if (getBrokerKey() == null) 192 { 193 198 throw new OJBRuntimeException("Can't find associated PBKey. Need PBKey to obtain a valid" + 199 "PersistenceBroker instance from intern resources."); 200 } 201 broker = PersistenceBrokerThreadMapping.currentPersistenceBroker(getBrokerKey()); 203 if ((broker == null) || broker.isClosed()) 205 { 206 broker = (PersistenceBrokerInternal) PersistenceBrokerFactory.createPersistenceBroker(getBrokerKey()); 207 208 needsClose = true; 209 } 210 return new TemporaryBrokerWrapper(broker, needsClose); 211 } 212 213 270 public Object invoke(Object proxy, Method method, Object [] args) 271 { 272 Object subject; 273 String methodName = method.getName(); 274 275 try 276 { 277 if ("finalize".equals(methodName) && _realSubject == null) 281 { 282 return null; 283 } 284 285 if ("writeReplace".equals(methodName)) 289 { 290 if (_realSubject == null) 291 { 292 return generateSerializableProxy(); 297 } else 298 { 299 return getRealSubject(); 303 } 304 } 305 306 317 318 331 332 if ("equals".equals(methodName) && args[0] != null) 335 { 336 TemporaryBrokerWrapper tmp = getBroker(); 337 try 338 { 339 args[0] = tmp.broker.getProxyFactory().getRealObject(args[0]); 340 } 341 finally 342 { 343 tmp.close(); 344 } 345 } 346 347 if ("getIndirectionHandler".equals(methodName) && args[0] != null) 348 { 349 return this; 350 } 351 352 subject = getRealSubject(); 353 return method.invoke(subject, args); 354 } catch (Exception ex) 362 { 363 throw new PersistenceBrokerException("Error invoking method " + method.getName(), ex); 364 } 365 } 366 367 373 public Object getRealSubject() throws PersistenceBrokerException 374 { 375 if (_realSubject == null) 376 { 377 beforeMaterialization(); 378 _realSubject = materializeSubject(); 379 afterMaterialization(); 380 } 381 return _realSubject; 382 } 383 384 389 public void setRealSubject(Object object) 390 { 391 _realSubject = object; 392 } 393 394 400 protected synchronized Object materializeSubject() throws PersistenceBrokerException 401 { 402 TemporaryBrokerWrapper tmp = getBroker(); 403 try 404 { 405 Object realSubject = tmp.broker.getObjectByIdentity(_id); 406 if (realSubject == null) 407 { 408 LoggerFactory.getLogger(IndirectionHandler.class).warn( 409 "Can not materialize object for Identity " + _id + " - using PBKey " + getBrokerKey()); 410 } 411 return realSubject; 412 } catch (Exception ex) 413 { 414 throw new PersistenceBrokerException(ex); 415 } finally 416 { 417 tmp.close(); 418 } 419 } 420 421 426 public boolean alreadyMaterialized() 427 { 428 return _realSubject != null; 429 } 430 431 436 private Object generateSerializableProxy() 437 { 438 return new OJBSerializableProxy(getIdentity().getObjectsRealClass(), this); 439 } 440 441 447 static final class TemporaryBrokerWrapper 448 { 449 450 boolean needsClose; 451 PersistenceBrokerInternal broker; 452 453 public TemporaryBrokerWrapper(PersistenceBrokerInternal broker, boolean needsClose) 454 { 455 this.broker = broker; 456 this.needsClose = needsClose; 457 } 458 459 463 public void close() 464 { 465 if(needsClose) 466 { 467 broker.close(); 468 } 469 } 470 } 471 } 472 | Popular Tags |