1 package org.apache.ojb.broker.core.proxy; 2 3 17 18 import java.lang.reflect.Constructor ; 19 import java.lang.reflect.InvocationTargetException ; 20 import java.lang.reflect.Modifier ; 21 import java.util.Collection ; 22 import java.util.List ; 23 import java.util.Set ; 24 25 import org.apache.ojb.broker.Identity; 26 import org.apache.ojb.broker.ManageableCollection; 27 import org.apache.ojb.broker.PBKey; 28 import org.apache.ojb.broker.PersistenceBrokerException; 29 import org.apache.ojb.broker.metadata.MetadataException; 30 import org.apache.ojb.broker.query.Query; 31 import org.apache.ojb.broker.util.configuration.impl.OjbConfigurator; 32 import org.apache.ojb.broker.util.logging.Logger; 33 import org.apache.ojb.broker.util.logging.LoggerFactory; 34 35 41 public abstract class AbstractProxyFactory implements ProxyFactory 42 { 43 48 49 private static Logger log = LoggerFactory.getLogger(AbstractProxyFactory.class); 50 private static transient ProxyFactory singleton; 51 52 53 private Class _indirectionHandlerClass; 54 55 private transient Constructor _indirectionHandlerConstructor; 56 57 private Constructor _listProxyConstructor; 58 59 private Constructor _setProxyConstructor; 60 61 private Constructor _collectionProxyConstructor; 62 63 private static ProxyConfiguration getProxyConfiguration() 64 { 65 return (ProxyConfiguration) OjbConfigurator.getInstance().getConfigurationFor(null); 66 } 67 68 73 private synchronized Constructor getIndirectionHandlerConstructor() 74 { 75 if(_indirectionHandlerConstructor == null) 76 { 77 Class [] paramType = {PBKey.class, Identity.class}; 78 79 try 80 { 81 _indirectionHandlerConstructor = getIndirectionHandlerClass().getConstructor(paramType); 82 } 83 catch(NoSuchMethodException ex) 84 { 85 throw new MetadataException("The class " 86 + _indirectionHandlerClass.getName() 87 + " specified for IndirectionHandlerClass" 88 + " is required to have a public constructor with signature (" 89 + PBKey.class.getName() 90 + ", " 91 + Identity.class.getName() 92 + ")."); 93 } 94 } 95 return _indirectionHandlerConstructor; 96 } 97 98 103 public Class getIndirectionHandlerClass() 104 { 105 if(_indirectionHandlerClass == null) 106 { 107 setIndirectionHandlerClass(getProxyConfiguration().getIndirectionHandlerClass()); 108 } 109 110 return _indirectionHandlerClass; 111 } 112 113 118 public void setIndirectionHandlerClass(Class indirectionHandlerClass) 119 { 120 if(indirectionHandlerClass == null) 121 { 122 128 indirectionHandlerClass = getDefaultIndirectionHandlerClass(); 129 } 130 if(indirectionHandlerClass.isInterface() 131 || Modifier.isAbstract(indirectionHandlerClass.getModifiers()) 132 || !getIndirectionHandlerBaseClass().isAssignableFrom(indirectionHandlerClass)) 133 { 134 throw new MetadataException("Illegal class " 135 + indirectionHandlerClass.getName() 136 + " specified for IndirectionHandlerClass. Must be a concrete subclass of " 137 + getIndirectionHandlerBaseClass().getName()); 138 } 139 _indirectionHandlerClass = indirectionHandlerClass; 140 } 141 142 149 public IndirectionHandler createIndirectionHandler(PBKey brokerKey, Identity id) 150 { 151 Object args[] = {brokerKey, id}; 152 153 try 154 { 155 return (IndirectionHandler) getIndirectionHandlerConstructor().newInstance(args); 156 } 157 catch(InvocationTargetException ex) 158 { 159 throw new PersistenceBrokerException("Exception while creating a new indirection handler instance", ex); 160 } 161 catch(InstantiationException ex) 162 { 163 throw new PersistenceBrokerException("Exception while creating a new indirection handler instance", ex); 164 } 165 catch(IllegalAccessException ex) 166 { 167 throw new PersistenceBrokerException("Exception while creating a new indirection handler instance", ex); 168 } 169 } 170 171 180 private static Constructor retrieveCollectionProxyConstructor(Class proxyClass, Class baseType, String typeDesc) 181 { 182 if(proxyClass == null) 183 { 184 throw new MetadataException("No " + typeDesc + " specified."); 185 } 186 if(proxyClass.isInterface() || Modifier.isAbstract(proxyClass.getModifiers()) || !baseType.isAssignableFrom(proxyClass)) 187 { 188 throw new MetadataException("Illegal class " 189 + proxyClass.getName() 190 + " specified for " 191 + typeDesc 192 + ". Must be a concrete subclass of " 193 + baseType.getName()); 194 } 195 196 Class [] paramType = {PBKey.class, Class .class, Query.class}; 197 198 try 199 { 200 return proxyClass.getConstructor(paramType); 201 } 202 catch(NoSuchMethodException ex) 203 { 204 throw new MetadataException("The class " 205 + proxyClass.getName() 206 + " specified for " 207 + typeDesc 208 + " is required to have a public constructor with signature (" 209 + PBKey.class.getName() 210 + ", " 211 + Class .class.getName() 212 + ", " 213 + Query.class.getName() 214 + ")."); 215 } 216 } 217 218 223 public Class getListProxyClass() 224 { 225 return getListProxyConstructor().getDeclaringClass(); 226 } 227 228 233 private Constructor getListProxyConstructor() 234 { 235 if(_listProxyConstructor == null) 236 { 237 setListProxyClass(getProxyConfiguration().getListProxyClass()); 238 } 239 return _listProxyConstructor; 240 } 241 242 249 public void setListProxyClass(Class listProxyClass) 250 { 251 _listProxyConstructor = retrieveCollectionProxyConstructor(listProxyClass, List .class, "ListProxyClass"); 252 } 253 254 259 public Class getSetProxyClass() 260 { 261 return getSetProxyConstructor().getDeclaringClass(); 262 } 263 264 269 private Constructor getSetProxyConstructor() 270 { 271 if(_setProxyConstructor == null) 272 { 273 setSetProxyClass(getProxyConfiguration().getSetProxyClass()); 274 } 275 return _setProxyConstructor; 276 } 277 278 283 public void setSetProxyClass(Class setProxyClass) 284 { 285 _setProxyConstructor = retrieveCollectionProxyConstructor(setProxyClass, Set .class, "SetProxyClass"); 286 } 287 288 293 public Class getCollectionProxyClass() 294 { 295 return getCollectionProxyConstructor().getDeclaringClass(); 296 } 297 298 303 private Constructor getCollectionProxyConstructor() 304 { 305 if(_collectionProxyConstructor == null) 306 { 307 setCollectionProxyClass(getProxyConfiguration().getCollectionProxyClass()); 308 } 309 return _collectionProxyConstructor; 310 } 311 312 317 public void setCollectionProxyClass(Class collectionProxyClass) 318 { 319 _collectionProxyConstructor = retrieveCollectionProxyConstructor(collectionProxyClass, Collection .class, "CollectionProxyClass"); 320 if(!ManageableCollection.class.isAssignableFrom(collectionProxyClass)) 322 { 323 throw new MetadataException("Illegal class " 324 + collectionProxyClass.getName() 325 + " specified for CollectionProxyClass. Must be a concrete subclass of " 326 + ManageableCollection.class.getName()); 327 } 328 } 329 330 336 private Constructor getCollectionProxyConstructor(Class collectionClass) 337 { 338 if(List .class.isAssignableFrom(collectionClass)) 339 { 340 return getListProxyConstructor(); 341 } 342 else if(Set .class.isAssignableFrom(collectionClass)) 343 { 344 return getSetProxyConstructor(); 345 } 346 else 347 { 348 return getCollectionProxyConstructor(); 349 } 350 } 351 352 360 public ManageableCollection createCollectionProxy(PBKey brokerKey, Query query, Class collectionClass) 361 { 362 Object args[] = {brokerKey, collectionClass, query}; 363 364 try 365 { 366 return (ManageableCollection) getCollectionProxyConstructor(collectionClass).newInstance(args); 367 } 368 catch(InstantiationException ex) 369 { 370 throw new PersistenceBrokerException("Exception while creating a new collection proxy instance", ex); 371 } 372 catch(InvocationTargetException ex) 373 { 374 throw new PersistenceBrokerException("Exception while creating a new collection proxy instance", ex); 375 } 376 catch(IllegalAccessException ex) 377 { 378 throw new PersistenceBrokerException("Exception while creating a new collection proxy instance", ex); 379 } 380 } 381 382 388 public final Object getRealObject(Object objectOrProxy) 389 { 390 if(isNormalOjbProxy(objectOrProxy)) 391 { 392 String msg; 393 394 try 395 { 396 return getIndirectionHandler(objectOrProxy).getRealSubject(); 397 } 398 catch(ClassCastException e) 399 { 400 msg = "The InvocationHandler for the provided Proxy was not an instance of " + IndirectionHandler.class.getName(); 402 log.error(msg); 403 throw new PersistenceBrokerException(msg, e); 404 } 405 catch(IllegalArgumentException e) 406 { 407 msg = "Could not retrieve real object for given Proxy: " + objectOrProxy; 408 log.error(msg); 409 throw new PersistenceBrokerException(msg, e); 410 } 411 catch(PersistenceBrokerException e) 412 { 413 log.error("Could not retrieve real object for given Proxy: " + objectOrProxy); 414 throw e; 415 } 416 } 417 else if(isVirtualOjbProxy(objectOrProxy)) 418 { 419 try 420 { 421 return ((VirtualProxy) objectOrProxy).getRealSubject(); 422 } 423 catch(PersistenceBrokerException e) 424 { 425 log.error("Could not retrieve real object for VirtualProxy: " + objectOrProxy); 426 throw e; 427 } 428 } 429 else 430 { 431 return objectOrProxy; 432 } 433 } 434 435 441 public Object getRealObjectIfMaterialized(Object objectOrProxy) 442 { 443 if(isNormalOjbProxy(objectOrProxy)) 444 { 445 String msg; 446 447 try 448 { 449 IndirectionHandler handler = getIndirectionHandler(objectOrProxy); 450 451 return handler.alreadyMaterialized() ? handler.getRealSubject() : null; 452 } 453 catch(ClassCastException e) 454 { 455 msg = "The InvocationHandler for the provided Proxy was not an instance of " + IndirectionHandler.class.getName(); 457 log.error(msg); 458 throw new PersistenceBrokerException(msg, e); 459 } 460 catch(IllegalArgumentException e) 461 { 462 msg = "Could not retrieve real object for given Proxy: " + objectOrProxy; 463 log.error(msg); 464 throw new PersistenceBrokerException(msg, e); 465 } 466 catch(PersistenceBrokerException e) 467 { 468 log.error("Could not retrieve real object for given Proxy: " + objectOrProxy); 469 throw e; 470 } 471 } 472 else if(isVirtualOjbProxy(objectOrProxy)) 473 { 474 try 475 { 476 VirtualProxy proxy = (VirtualProxy) objectOrProxy; 477 478 return proxy.alreadyMaterialized() ? proxy.getRealSubject() : null; 479 } 480 catch(PersistenceBrokerException e) 481 { 482 log.error("Could not retrieve real object for VirtualProxy: " + objectOrProxy); 483 throw e; 484 } 485 } 486 else 487 { 488 return objectOrProxy; 489 } 490 } 491 492 498 public Class getRealClass(Object objectOrProxy) 499 { 500 IndirectionHandler handler; 501 502 if(isNormalOjbProxy(objectOrProxy)) 503 { 504 String msg; 505 506 try 507 { 508 handler = getIndirectionHandler(objectOrProxy); 509 513 return handler.getIdentity().getObjectsRealClass(); 515 } 516 catch(ClassCastException e) 517 { 518 msg = "The InvocationHandler for the provided Proxy was not an instance of " + IndirectionHandler.class.getName(); 520 log.error(msg); 521 throw new PersistenceBrokerException(msg, e); 522 } 523 catch(IllegalArgumentException e) 524 { 525 msg = "Could not retrieve real object for given Proxy: " + objectOrProxy; 526 log.error(msg); 527 throw new PersistenceBrokerException(msg, e); 528 } 529 } 530 else if(isVirtualOjbProxy(objectOrProxy)) 531 { 532 handler = VirtualProxy.getIndirectionHandler((VirtualProxy) objectOrProxy); 533 537 return handler.getIdentity().getObjectsRealClass(); 539 } 540 else 541 { 542 return objectOrProxy.getClass(); 543 } 544 } 545 546 551 public boolean isNormalOjbProxy(Object proxyOrObject) 552 { 553 return proxyOrObject instanceof OJBProxy; 554 } 555 556 561 public boolean isVirtualOjbProxy(Object proxyOrObject) 562 { 563 return proxyOrObject instanceof VirtualProxy; 564 } 565 566 570 public boolean isProxy(Object proxyOrObject) 571 { 572 return isNormalOjbProxy(proxyOrObject) || isVirtualOjbProxy(proxyOrObject); 573 } 574 575 579 protected abstract IndirectionHandler getDynamicIndirectionHandler(Object obj); 580 581 588 public IndirectionHandler getIndirectionHandler(Object obj) 589 { 590 if(obj == null) 591 { 592 return null; 593 } 594 else if(isNormalOjbProxy(obj)) 595 { 596 return getDynamicIndirectionHandler(obj); 597 } 598 else if(isVirtualOjbProxy(obj)) 599 { 600 return VirtualProxy.getIndirectionHandler((VirtualProxy) obj); 601 } 602 else 603 { 604 return null; 605 } 606 607 } 608 609 616 public boolean isMaterialized(Object object) 617 { 618 IndirectionHandler handler = getIndirectionHandler(object); 619 620 return handler == null || handler.alreadyMaterialized(); 621 } 622 623 624 public CollectionProxy getCollectionProxy(Object item) 625 { 626 if(isCollectionProxy(item)) 627 { 628 return (CollectionProxy) item; 629 } 630 else 631 { 632 return null; 633 } 634 } 635 636 641 public boolean isCollectionProxy(Object item) 642 { 643 return (item instanceof CollectionProxy); 644 } 645 646 655 public String toString(Object proxy) 656 { 657 IndirectionHandler handler = getIndirectionHandler(proxy); 658 if((handler != null) && handler.alreadyMaterialized()) 659 { 660 return "unmaterialized proxy for " + handler.getIdentity(); 661 } 662 else 663 { 664 return proxy.toString(); 665 } 666 } 667 668 public synchronized static ProxyFactory getProxyFactory() 669 { 670 675 if(singleton == null) 676 { 677 Class proxyFactoryClass = null; 678 try 679 { 680 proxyFactoryClass = getProxyConfiguration().getProxyFactoryClass(); 681 singleton = (ProxyFactory) proxyFactoryClass.newInstance(); 682 } 683 catch(InstantiationException e) 684 { 685 throw new MetadataException("Illegal class " + proxyFactoryClass.getName() + " specified for ProxyFactoryClass."); 686 } 687 catch(IllegalAccessException e) 688 { 689 throw new MetadataException("Illegal class " + proxyFactoryClass.getName() + " specified for ProxyFactoryClass."); 690 } 691 } 692 return singleton; 693 } 694 695 } 696 | Popular Tags |