Summary: - proposal for component management in avalon 5: 1) removal of ComponentSelector 2) removal of release() 3) replacement of Component with Object 4) replacement of ComponentException with exists() for lookup() 5) addition of an _optional_ lookup() method that supports hints, to enable smooth migration from ComponentSelector usage
- rationale behind proposal. #5 is point of debate. Current proposal allows smooth migration for Cocoon and other client code; I cannot think of a better way to allow this. - analysis of backwards-compatibility. Changes are required, but they're not world-shocking and it should be possible to write a tool to automatically make 99% of these changes. - course of action cheers! Leo Simons PROPOSAL ======== /** * A ComponentManager is a simple lookup mechanism for * {@see $Components Components}. The lookup key is a {@see $Role role}, * possibly with a hint to further specify the lookup. Support for hints * in ComponentManager implementations is optional. * * <p>Typical usage:</p> * * <pre> * // inside your Component... * compose( ComponentManager cm ) throws ComponentException * { * if( cm.exists( MyComponent.ROLE ) ) * m_myComponent = cm.lookup( MyComponent.ROLE ); * * // more simple (no-hint) lookups here. * * // if the lookups below result in exceptions, the container will * // know what to do * * if( cm.exists( AnotherComponent.ROLE, * AnotherComponent.SOME_HINT ) ) * m_anotherComponent = cm.lookup( AnotherComponent.ROLE, * AnotherComponent.SOME_HINT ); * } * // ... * </pre> */ interface ComponentManager { /** * Look up a component. Make sure to verify it exists using * the exists() method before you do the lookup. * * @throws IllegalArgumentException if there is no component * inside the ComponentManager implementing the specified role. */ Object lookup( String role ); /** * Look up a component. Make sure to verify it exists using * the exists() method before you do the lookup. * * @throws UnsupportedOperationException if the * ComponentManager implementation does not support hints. * * @throws IllegalArgumentException if there is no component * inside the ComponentManager implementing the specified role * with the specified hint. */ Object lookup( String role, String hint ); /** * Determine whether a component with the specified * role exists in this ComponentManager. */ boolean exists( String role ); /** * Determine whether a component with the specified * role exists in this ComponentManager. * * @throws UnsupportedOperationException if the * ComponentManager implementation does not support hints. */ boolean exists( String role, String hint ); } RATIONALE ========= Discussions in January 2002 leading to the creation of the ServiceManager and recent discussions of avalon 5 raise some issues. Why no ComponentException? ========================== Since the ComponentManager is a simple lookup mechanism, the only possible cause for an error during lookup is that of a requested component not existing. The use of exists() follows common java practice, is clear to the API user and results in clean, performant code. While making ComponentException extend RuntimeException would likely be of no difference to the component developer, it seems more natural to remove it here, as IllegalArgumentException describes the problem perfectly. Why a lookup with a hint? ========================= Even though some of us may not like the use of hints, removing the concept of the ComponentSelector *and* no support for hints means that applications that used the ComponentSelector will have a very tough migration path. The introduction of hints does not hurt applications that do not need them, and allowing the IllegalArgumentException explicitly means that Containers have a simple mechanism for handling the case where they do not support them while a contained component does (the container passes in a CM that doesn't support hints, which results in an IllegalArgumentException during compose() in the component, which the container then catches and handles as appropriate). Why no release()? ================= The release() method has to do with resource management, which is not the concern of the ComponentManager. See recent discussions. Why no Component interface? =========================== The Component interface is a marker interface, which is considered a bad way to provide information on components, as it causes problems when integrating with existing component-oriented products like CORBA and EJB. See the discussions in January that led to creation of the ServiceManager. Why no ComponentSelector? ========================= See on-and-off discussion of this subject over the past 2 years. It requires horrid-looking, complex, client code. The Selector concept is replaced with the concept of lookup hints. While some of us believe (myself included) that the use of hints/sub-selectors in a directory-style lookup is a design fault, a provision for them should be made as client code depends on its existence. BACKWARD COMPATIBILITY ISSUES ============================= This change will require oversee-able changes to client source code. Migrating from Avalon 4 ComponentManager ======================================== Is relatively painless. Though it would be best to replace all occurrences of "lookup([-_0-9a-zA-Z]);" with "if(exists($1)) lookup($1);", if the application is assembled well, this is not necessary as the requested components will always be available. Another thing that needs to be done is to add the cast from Object to Component in all places where you use the Component interface. This is the same effort required when upgrading from a4 ComponentManager to a4 ServiceManager; it has been agreed upon in January 2002 this change is a good thing. Also, all calls to release() must be removed. This is not likely to cause problems. Migrating from Avalon 4 ServiceManager ====================================== Is relatively painless. Though it would be best to replace all occurrences of "lookup([-_0-9a-zA-Z]);" with "if(exists($1)) lookup($1);", if the application is assembled well, this is not necessary as the requested components will always be available. Also, all calls to release() must be removed. This is not likely to cause problems. Finally, all mention of ServiceManager must revert back to ComponentManager. Migrating from Avalon 4 ComponentManager + ComponentSelector ============================================================ Is the most difficult upgrade path, as all uses of ComponentSelector should be replaced by the use of hints. Typical example: // inside your Component... compose( ComponentManager cm ) throws ComponentException { // ... ComponentSelector selector = (ComponentSelector) cm.lookup(MyComponent.ROLE + "Selector"); myComponent = (MyComponent)selector.select( MyComponent.SOME_HINT); // ... } // ... // inside your Component... compose( ComponentManager cm ) { // ... if( cm.exists( MyComponent.ROLE, MyComponent.SOME_HINT ) ) m_myComponent = cm.lookup( MyComponent.ROLE, MyComponent.SOME_HINT ); // ... } // ... Migration Automation ==================== It should be possible to write migration tools that automate this upgrade process. COURSE OF ACTION ================ (on proposal acceptance) - The next release of Avalon Framework v4 should document the changes we intend to make, so component developers can anticipate the changes that will need to be made to migrate to v5. - The interface should be added to the v5 proposal - evaluation of the necessity of a migration tool should be evaluated and added to the TODO list if it is considered required. -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>