commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rsi...@apache.org
Subject cvs commit: jakarta-commons/discovery best-practices.html
Date Sat, 27 Jul 2002 21:50:11 GMT
rsitze      2002/07/27 14:50:10

  Modified:    discovery best-practices.html
  Log:
  Added group context discussion
  
  Revision  Changes    Path
  1.2       +226 -175  jakarta-commons/discovery/best-practices.html
  
  Index: best-practices.html
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/discovery/best-practices.html,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- best-practices.html	18 Jul 2002 18:31:36 -0000	1.1
  +++ best-practices.html	27 Jul 2002 21:50:10 -0000	1.2
  @@ -9,9 +9,10 @@
   <h1>Best Practices for using Jakarta Commons "Discovery" Component</h1>
   $Id$<br />
   <a href="#Introduction">[Introduction]</a>
  -<a href="#Integrating into Factories : Wrapping">[Integrating into Factories : Wrapping]</a>
   <a href="#Calling Directly">[Calling Directly]</a>
  +<a href="#Integrating into Factories : Wrapping">[Integrating into Factories : Wrapping]</a>
   <a href="#Service Life Cycle Management">[Service Life Cycle Management]</a>
  +<a href="#Service Groups">[Service Groups]</a>
   <br /><br />
   </div>
   
  @@ -20,15 +21,84 @@
   <h3>1.  INTRODUCTION</h3>
   
   Best-practices are discussed.
  -See the javadoc for detail on the API,
  -where service implementation overrides are looked for,
  +See the javadoc 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="Calling Directly"></a>
  +<h3>2.  CALLING DIRECTLY</h3>
  +
  +
  +<p>To call discovery directly from user-code, looking for a service.
  +<ul>
  +<pre>
  +    import org.apache.commons.discovery.Discovery;
  +    import org.apache.commons.logging.Log;
  +    ...
  +    Log log = (Log)Discovery.find(Log.class);
  +</pre>
  +</ul>
  +Discovery looks for the value of the system property
  +<code>org.apache.commons.logging.Log</code>
  +for the name of the class implementing that interface,
  +and failing that uses JDK1.3-style service discovery.
  +</p>
  +<p>
  +This should be sufficient for many new applications,
  +however, in this case, the commons-logging API
  +provides a <code>LogFactory</code> class that
  +provides additional benefits, including a series of
  +fall-back logger implementations
  +(see commons-logging guidelines for best-practices related to that component),
  +and preserves backward compatible configuration/property names.
  +So, the following may be appropriate:
  +<ul>
  +<pre>
  +    import org.apache.commons.logging.LogFactory;
  +    ...
  +    LogFactory factory = (LogFactory)Discovery.find(LogFactory.class);
  +    Log log = factory.getInstance();
  +</pre>
  +</ul>
  +</p>
  +<p>
  +Discovery 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)Discovery.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)Discovery.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>Discovery</code>, review the javadoc for
  +other forms and options available.
  +</p>
  +
   <a name="Integrating into Factories : Wrapping"></a>
  -<h3>2.  INTEGRATING INTO FACTORIES : WRAPPING</h3>
  +<h3>3.  INTEGRATING INTO FACTORIES : WRAPPING</h3>
   
   
   <p>In this example, a factory (such as is used in commons-logging)
  @@ -36,149 +106,66 @@
   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.
  -</p>
  -
  -<p>Note the javadoc in the example below which explains
  -the parameters.</p>
   
   <ul>
  -<code>
  -import java.util.Properties;<br>
  -import org.apache.commons.discovery.Discovery;<br>
  -import org.apache.commons.discovery.DiscoveryException;<br>
  -<br>
  -public abstract class LogFactory<br>
  -{<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;protected static final String FACTORY_DEFAULT =<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;org.apache.commons.logging.impl.DefaultLogFactory.class.getName();<br>
  -<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;protected static final String FACTORY_PROPERTIES
=<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"commons-logging.properties";<br>
  -<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;/**<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * Protected constructor that is not available
for public use.<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; */<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;protected LogFactory() { }<br>
  -<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;/**<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * Locate and construct LogFactory using discovery
logic.<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * <br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * The first parameter is the <code>rootFinderClass</code>
which is<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * the interface/class representing the wrapper/factory,
or this class.<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * This allows <code>Discovery.find()</code>
to identify an appropriate<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * class loader where it can expect to find an
implementation (default<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * class loader at a minimum, in this case).<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * <br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * The second parameter is the <code>spi</code>
or service provider<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * interface for which an implementation is desired.
 In this case, both<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * the factory and spi are represented by the same
(abstract) class.<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * <br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * The third parameter is the name of a properties
file which will be<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * loaded.  It may be used to attempt to find a
property specifying the<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * service implementation (property named <code>LogFactory.class.getName()</code>.<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * <br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * The fourth parameter is the name of a default
implementation class.<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * <br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * @exception DiscoveryException if the implementation
class is not<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; *            available or cannot be instantiated.<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; */<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;public static LogFactory getFactory() throws ServiceException<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;{<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return
(LogFactory)Discovery.find(LogFactory.class,<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogFactory.class,<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FACTORY_PROPERTIES,<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FACTORY_DEFAULT);<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;}<br>
  -<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;/**<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * Locate and construct LogFactory using discovery
logic.<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * <br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * @param properties use properties instead of
FACTORY_PROPERTIES default<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; *        for discovery.<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * <br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * @exception DiscoveryException if the implementation
class is not<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; *            available or cannot be instantiated.<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; */<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;public static LogFactory getFactory(Properties
properties)<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throws
ServiceException<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;{<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return
(LogFactory)Discovery.find(LogFactory.class,<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogFactory.class,<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;properties,<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FACTORY_DEFAULT);<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;}<br>
  -}<br>
  -</code>
  +<pre>
  +import java.util.Properties;
  +import org.apache.commons.discovery.Discovery;
  +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)Discovery.find(LogFactory.class,
  +                                          LogFactory.class,
  +                                          FACTORY_PROPERTIES,
  +                                          FACTORY_DEFAULT);
  +    }
  +
  +    public static LogFactory getFactory(Properties properties)
  +        throws ServiceException
  +    {
  +        return (LogFactory)Discovery.find(LogFactory.class,
  +                                          LogFactory.class,
  +                                          properties,
  +                                          FACTORY_DEFAULT);
  +    }
  +    ...
  +}
  +</pre>
   </ul>
  - 
  -<a name="Calling Directly"></a>
  -<h3>3.  CALLING DIRECTLY</h3>
  -
  -
  -<p>In these examples, the discovery is called directly a 'user'.
  +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>
  -
  -<ul>
  -<code>
  -&nbsp;&nbsp;&nbsp;&nbsp;/**<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * Locate and construct LogFactory using discovery
logic.<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * <br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * The first parameter is the <code>spi</code>
or service provider<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * interface for which an implementation is desired.
 In this case, both<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * the factory and spi are represented by the same
(abstract) class.<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * <br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * The second parameter is the name of a properties
file which will be<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * loaded.  It may be used to attempt to find a
property specifying the<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * service implementation (property named <code>LogFactory.class.getName()</code>.<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * <br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * The third parameter is the name of a default
implementation class.<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; */<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;LogFactory factory = (LogFactory)Discovery.find(LogFactory.class,<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  -&nbsp;&nbsp;&nbsp;&nbsp;LogFactory.FACTORY_PROPERTIES,<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  -&nbsp;&nbsp;&nbsp;&nbsp;LogFactory.FACTORY_DEFAULT);<br>
  -<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;/**<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * Locate and construct LogFactory using discovery
logic.<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * <br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * Use <code>properties</code> instead
of FACTORY_PROPERTIES default<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * for discovery.<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; */<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;LogFactory factory = (LogFactory)Discovery.find(LogFactory.class,<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;properties,<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogFactory.FACTORY_DEFAULT);<br>
  -</code>
  -</ul>
  -
  + 
   <a name="Service Life Cycle Management"></a>
   <h3>4.  SERVICE LIFE CYCLE MANAGEMENT</h3>
   
   <p>Discovery supports life-cycle management through the <code>Service</code>
interface.
   If service implementation implements
  -the <code>Service</code> interface then an <code>init(Properties)</code>
  +the <code>Service</code> interface then an
  +<code>init(String, Properties)</code>
   method is invoked when the class in created by Discovery.
   Likewise, a <code>release()</code> method is invoked when Discovery
   removes the service from it's internal cache.
  @@ -188,50 +175,114 @@
   might be extended as follows:
   
   <ul>
  -<code>
  -<b>import org.apache.commons.discovery.Service;</b><br>
  -<br>
  -public abstract class LogFactory <b>implements Service</b><br>
  -{<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;. . .<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;<b>public abstract void init(Properties properties);<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;public abstract void release();<br>
  -<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;/**<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * Release any internal references to previously
created {@link LogFactory}<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * instances, after calling the instance method
<code>release()</code> on<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * each of them.  This is useful environments like
servlet containers,<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * which implement application reloading by throwing
away a ClassLoader.<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * Dangling references to objects in that class
loader would prevent<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; * garbage collection.<br>
  -&nbsp;&nbsp;&nbsp;&nbsp; */<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;public static void releaseAll() {<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Discovery.releaseAll(LogFactory.class);<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;}</b><br>
  -}<br>
  -</code>
  +<pre>
  +<b>import org.apache.commons.discovery.Service;</b>
  +
  +public abstract class LogFactory <b>implements Service</b>
  +{
  +    . . .
  +    <b>public abstract void init(String groupContext, Properties properties);</b>
  +    <b>public abstract void release();</b>
  +
  +    /**
  +     * Release any internal references to previously created {@link LogFactory}
  +     * instances, after calling the instance method <code>release()</code>
on
  +     * each of them.  This is useful environments like servlet containers,
  +     * which implement application reloading by throwing away a ClassLoader.
  +     * Dangling references to objects in that class loader would prevent
  +     * garbage collection.
  +     */
  +    <b>public static void releaseAll() {</b>
  +        <b>Discovery.releaseAll(LogFactory.class);</b>
  +    <b>}</b>
  +}
  +</pre>
   </ul>
   
   <p>An example of how the properties might be used:
   </p>
   <ul>
  -<code>
  -<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;public void init(Properties properties) {<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (properties
!= null) {<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Enumeration
names = properties.propertyNames();<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while
(names.hasMoreElements()) {<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String
name = (String)names.nextElement();<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setAttribute(name,
properties.getProperty(name));<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;}<br>
  -<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;public abstract void setAttribute(String name,
Object value);<br>
  -&nbsp;&nbsp;&nbsp;&nbsp;public abstract Object getAttribute(String name);<br>
  -</code>
  +<pre>
  +    public abstract void setAttribute(String name, Object value); 
  +    public abstract Object getAttribute(String name); 
  + 
  +    public void init(String groupContext, Properties properties) {
  +        if (properties != null) {
  +            Enumeration names = properties.propertyNames();
  +            while (names.hasMoreElements()) {
  +                String name = (String)names.nextElement();
  +                setAttribute(name, properties.getProperty(name));
  +            }
  +        }
  +    }
  +</pre>
   </ul>
   
  + 
  +<a name="Service Groups"></a>
  +<h3>4.  Service Groups</h3>
  +
  +<p>The <code>Service.init<code> method includes
  +a <code>groupContext</code> parameter.
  +This parameter allows services to be discovered and categorized by different
  +groups.
  +</p>
  +
  +<p>
  +When a service is located and loaded,
  +it is done so within the context
  +of a set of <i>properties</i> and a runtime environment
  +(in particular, the ClassLoader hierarchy).
  +It is cached by the <code>Discovery</code>.
  +What happens when a different configuration is desired?
  +</p>
  +
  +<p>
  +The service <code>groupContext</code> parameter,
  +available for many forms of <code>Discovery.find</code>,
  +allows services to be discovered and cached
  +by common groups, independent of other groups.
  +</p>
  +
  +<p>
  +It is suggested that service components that
  +<ul>
  +<li>use <code>Discovery</code> services, and that</li>
  +<li>provide a service (i.e. could be discovered)</li>
  +</ul>
  +accept the <code>groupContext</code> and propogate
  +it through to services it discovers.
  +The groupContext should be optional,
  +so two forms of each 'discovery' wrapper method
  +should be used:
  +<ul>
  +<pre>
  +    public static LogFactory getFactory() throws ServiceException
  +    ... as above ...
  +
  +    public static LogFactory getFactory(Properties properties)
  +    ... as above ...
  +
  +    public static LogFactory getFactory(<b>String groupContext</b>)
  +        throws ServiceException
  +    {
  +        return (LogFactory)Discovery.find(LogFactory.class,
  +                                          <b>groupContext</b>, LogFactory.class,
  +                                          FACTORY_PROPERTIES,
  +                                          FACTORY_DEFAULT);
  +    }
  +
  +    public static LogFactory getFactory(<b>String groupContext,</b>
  +                                        Properties properties)
  +        throws ServiceException
  +    {
  +        return (LogFactory)Discovery.find(LogFactory.class,
  +                                          <b>groupContext</b>, LogFactory.class,
  +                                          properties,
  +                                          FACTORY_DEFAULT);
  +    }
  +</pre>
  +</ul>
   
   </body>
   </html>
  
  
  

--
To unsubscribe, e-mail:   <mailto:commons-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:commons-dev-help@jakarta.apache.org>


Mime
View raw message