bayard 2004/02/18 02:14:01 Added: discovery/xdocs adc-guidelines.xml best-practices.xml Log: documentation moved from html to xml, by use of script Revision Changes Path 1.1 jakarta-commons/discovery/xdocs/adc-guidelines.xml Index: adc-guidelines.xml =================================================================== <document> <properties> <title>Architecture/Design/Coding Guidelines for Jakarta Commons "Discovery" Component</title> </properties> <body> <section name="Architecture/Design/Coding Guidelines for Jakarta Commons "Discovery" Component"> $Id: adc-guidelines.xml,v 1.1 2004/02/18 10:14:01 bayard Exp $<br/> <a href="#Introduction">[Introduction]</a> <a href="#Security and doPrivileged()">[Security and doPrivileged()]</a> <br/><br/> <a name="Introduction"></a> <subsection name="1. Introduction"> Kick-off: set of design/architectural guidelines. This should serve as both a record of decisions made, and a list of open issues. <a name="Security and doPrivileged()"></a> </subsection> <subsection name="2. Security and doPrivileged()"> Do not use doPrivileged() instructions within discovery. That remains the responsibility of the end-user. </subsection> </section> </body> </document> 1.1 jakarta-commons/discovery/xdocs/best-practices.xml Index: best-practices.xml =================================================================== <document> <properties> <title>Best Practices for using Jakarta Commons "Discovery" Component</title> </properties> <body> <section name="Best Practices for using Jakarta Commons "Discovery" Component"> $Id: best-practices.xml,v 1.1 2004/02/18 10:14:01 bayard Exp $<br /> <a href="#Introduction">[Introduction]</a> <a href="#Discovery Services">[Discovery Services]</a> <a href="#Additional Tools">[Additional Tools]</a> <a href="#Calling Directly">[Calling Directly]</a> <a href="#Integrating into Factories : Wrapping">[Integrating into Factories : Wrapping]</a> <br /><br /> <a name="Introduction"></a> <subsection name="1. INTRODUCTION"> Best-practices are discussed. See the javadoc, starting with <code>DiscoverySingleton</code> and <code>DiscoverClass</code>, for detail on the API: where service implementations are looked for, the order in which those places are checked, which classloaders are used, and the order in which they are used. <a name="Discovery Services"></a> </subsection> <subsection name="2. DISCOVERY SERVICES"> <a name="Additional Tools"></a> </subsection> <subsection name="3. ADDITIONAL TOOLS"> <a name="Calling Directly"></a> <h4>3.1. CALLING DIRECTLY</h4> <a name="Finding Singleton Instances (Factories)"></a> <h5>3.1.1. Finding Singleton Instances (Factories)</h5> <p>DiscoverSingleton finds, loads, and manages the lifecycle of a class implementing a given interface. It only supports classes with default (zero-argument) constructors. DiscoverSingleton can pass a set of properties to the class (see <a href="#Service Life Cycle Management">[Service Life Cycle Management]</a>). Use of the term singleton should be applied loosely: DiscoverSingleton will instantiate separate instances of a class if called with different: <ul> <li>thread context class loaders (for example, within different web applications in a J2EE managed environment)</li> <li>group contexts (maintain separation between different subsystems, if desired)</li> </ul> </p> <p>To call discovery directly from user-code: <ul> <pre> import org.apache.commons.discovery.DiscoverSingleton; import org.apache.commons.logging.LogFactory; ... LogFactory logFactory = (LogFactory)DiscoverSingleton.find(LogFactory.class); </pre> </ul> DiscoverSingleton looks for the value of the system property <code>org.apache.commons.logging.LogFactory</code> for the name of a class that implements the <code>LogFactory</code> (abstract) class. Failing that, it uses JDK1.3-style service discovery. </p> <p> DiscoverSingleton also allows a <code>java.util.Properties</code> parameter to be used for query for service implementation class name, as well as a default implementation class name: <ul> <pre> LogFactory factory = (LogFactory)DiscoverSingleton.find(LogFactory.class, properties, LogFactory.FACTORY_DEFAULT); </pre> </ul> </p> <p> The properties can also be specified as a resource name: <ul> <pre> LogFactory factory = (LogFactory)DiscoverSingleton.find(LogFactory.class, LogFactory.FACTORY_PROPERTIES, LogFactory.FACTORY_DEFAULT); </pre> </ul> This last form is equivalent in function to the original <code>LogFactory.getFactory()</code> method. </p> <p> There are a variety of <code>find</code> methods provided by <code>DiscoverSingleton</code>, review the javadoc for other forms and options available. </p> <a name="Finding Classes"></a> <h5>3.1.2. Finding Classes</h5> <p>DiscoverClass finds and loads a class implementing a given interface. DiscoverClass can pass a set of properties to the class if it implements the <code>Service</code> interface (which doesn't support full-lifecycle management as does the <code>SingletonService</code> interface). </p> <p> DiscoverClass provides API's that instantiate a class, though it currently supports only classes with default (zero-argument) constructors. Unlike <code>DiscoverySingleton</code>, class instances are not cached, so each call will result in a new object instance. </p> <p> DiscoverClass is more oriented toward calling multiple times within similar contexts, so it's use is slightly different than DiscoverSingleton: where as DiscoverSingleton provides a set of static methods (no state), DiscoverClass must be instantiated before it is used and maintains internal state. </p> <p>To find a class directly from user-code: [NEED BETTER EXAMPLE] <ul> <pre> import org.apache.commons.discovery.DiscoverClass; import org.apache.commons.logging.LogFactory; ... DiscoverClass discoverClass = new DiscoverClass(); Class logFactoryClass = (LogFactory)discoverClass.find(LogFactory.class); </pre> </ul> In this case, DiscoverClass looks for the value of the system property <code>org.apache.commons.logging.LogFactory</code> for the name of a class that implements the <code>LogFactory</code> (abstract) class. Failing that, it uses JDK1.3-style service discovery. </p> <p>To instantiate a class directly from user-code: [NEED BETTER EXAMPLE] <ul> <pre> import org.apache.commons.discovery.DiscoverClass; import org.apache.commons.logging.LogFactory; ... DiscoverClass discoverClass = new DiscoverClass(); LogFactory logFactoryClass = (LogFactory)discoverClass.newInstance(LogFactory.class); </pre> </ul> </p> <p> As with DiscoverSingleton, DiscoverClass provides methods that use <code>java.util.Properties</code> and a default implementation class name to help determine the name of the class. </p> <a name="Integrating into Factories : Wrapping"></a> <h4>3.2 INTEGRATING INTO FACTORIES : WRAPPING</h4> <p>In this example, a factory (such as is used in commons-logging) internalizes the discovery mechanism, passing appropriate defaults for a default properties file and a default implementation. In this case, the factory plays double duty as both the service to be discovered (abstract class), and the discovery mechanism. <ul> <pre> import java.util.Properties; import org.apache.commons.discovery.DiscoverSingleton; import org.apache.commons.discovery.DiscoveryException; public abstract class LogFactory { protected static final String FACTORY_DEFAULT = org.apache.commons.logging.impl.DefaultLogFactory.class.getName(); protected static final String FACTORY_PROPERTIES = "commons-logging.properties"; /** * Protected constructor that is not available for public use. */ protected LogFactory() { } public static LogFactory getFactory() throws ServiceException { return (LogFactory)DiscoverSingleton.find(LogFactory.class, LogFactory.class, FACTORY_PROPERTIES, FACTORY_DEFAULT); } public static LogFactory getFactory(Properties properties) throws ServiceException { return (LogFactory)DiscoverSingleton.find(LogFactory.class, LogFactory.class, properties, FACTORY_DEFAULT); } ... } </pre> </ul> Note the addition of one extra parameter to the <code>find</code> method call. The first parameter is a <i>root wrapper class</i>, which delegates to the discovery mechanism. This is necessary to all <code>Discovery</code> to determine the correct class loaders to be used in loading an implementation class. The second parameter is the service interface/class for which <code>Discovery</code> will be looking for an implementation. In this example, they are the same class, as the LogFactory is providing helper methods that 'wrap' <code>Discovery</code>. </p> </subsection> </section> </body> </document>
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]