Revision: 1471
          http://svn.sourceforge.net/spring-rich-c/?rev=1471&view=rev
Author:   mathiasbr
Date:     2006-10-02 00:53:34 -0700 (Mon, 02 Oct 2006)

Log Message:
-----------
implementations of application services must not be registered in 
DefaultApplicationServices any more if the bean name is defined by using the 
decapitalized short name of the service class. 

Modified Paths:
--------------
    
trunk/spring-richclient/samples/simple/src/main/resources/org/springframework/richclient/samples/simple/ctx/richclient-application-context.xml
    
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/application/support/DefaultApplicationServices.java

Modified: 
trunk/spring-richclient/samples/simple/src/main/resources/org/springframework/richclient/samples/simple/ctx/richclient-application-context.xml
===================================================================
--- 
trunk/spring-richclient/samples/simple/src/main/resources/org/springframework/richclient/samples/simple/ctx/richclient-application-context.xml
      2006-09-30 12:19:57 UTC (rev 1470)
+++ 
trunk/spring-richclient/samples/simple/src/main/resources/org/springframework/richclient/samples/simple/ctx/richclient-application-context.xml
      2006-10-02 07:53:34 UTC (rev 1471)
@@ -94,7 +94,10 @@
     <bean id="applicationServices"
         
class="org.springframework.richclient.application.support.DefaultApplicationServices">
         <property name="imageSourceId"><idref bean="imageSource"/></property>
+        <!-- It is not required to define each service bean here if the bean 
name maches the service type name like rulesSource.
+             The service implementation will still be found if the bean name 
uses the decapitalized short name of the service type.
         <property name="rulesSourceId"><idref bean="rulesSource"/></property>
+         -->
         <property name="conversionServiceId"><idref 
bean="conversionService"/></property>
         <property name="formComponentInterceptorFactoryId"><idref 
bean="formComponentInterceptorFactory"/></property>
         <property name="applicationObjectConfigurerId"><idref 
bean="applicationObjectConfigurer" /></property>

Modified: 
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/application/support/DefaultApplicationServices.java
===================================================================
--- 
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/application/support/DefaultApplicationServices.java
    2006-09-30 12:19:57 UTC (rev 1470)
+++ 
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/application/support/DefaultApplicationServices.java
    2006-10-02 07:53:34 UTC (rev 1471)
@@ -72,42 +72,46 @@
 import org.springframework.rules.reporting.DefaultMessageTranslatorFactory;
 import org.springframework.rules.reporting.MessageTranslatorFactory;
 import org.springframework.rules.support.DefaultRulesSource;
+import org.springframework.util.ClassUtils;
 
 /**
- * A default implementation of the ApplicationServices (service locator) 
interface. This
- * implementation allows for the direct registration of service 
implementations by using
- * various setter methods (like [EMAIL PROTECTED] 
#setImageSource(ImageSource)}). Service registry
- * entries can also be added in bulk using the [EMAIL PROTECTED] 
#setRegistryEntries(Map)} method.
+ * A default implementation of the ApplicationServices (service locator) 
interface. This implementation allows for the
+ * direct registration of service implementations by using various setter 
methods (like
+ * [EMAIL PROTECTED] #setImageSource(ImageSource)}). Service registry entries 
can also be added in bulk using the
+ * [EMAIL PROTECTED] #setRegistryEntries(Map)} method.
  * <p>
- * Except in testing environments, this class will typically be instantiated 
in the
- * application context and the various service implementations will be set 
<b>BY ID</b>.
- * The use of service bean ids instead of direct bean references is to avoid 
numerous
- * problems with cyclic dependencies and other order dependent operations. So, 
a typical
- * incarnation might look like this:
+ * Except in testing environments, this class will typically be instantiated 
in the application context and the various
+ * service implementations will be set <b>BY ID</b>. The use of service bean 
ids instead of direct bean references is
+ * to avoid numerous problems with cyclic dependencies and other order 
dependent operations. So, a typical incarnation
+ * might look like this:
  * 
  * <pre>
- *   &lt;bean id=&quot;applicationServices&quot;
- *       
class=&quot;org.springframework.richclient.application.support.DefaultApplicationServices&quot;&gt;
- *       &lt;property 
name=&quot;applicationObjectConfigurerId&quot;&gt;&lt;idref 
bean=&quot;applicationObjectConfigurer&quot; /&gt;&lt;/property&gt;
- *       &lt;property name=&quot;imageSourceId&quot;&gt;&lt;idref 
bean=&quot;imageSource&quot;/&gt;&lt;/property&gt;
- *       &lt;property name=&quot;rulesSourceId&quot;&gt;&lt;idref 
bean=&quot;rulesSource&quot;/&gt;&lt;/property&gt;
- *       &lt;property name=&quot;conversionServiceId&quot;&gt;&lt;idref 
bean=&quot;conversionService&quot;/&gt;&lt;/property&gt;
- *       &lt;property 
name=&quot;formComponentInterceptorFactoryId&quot;&gt;&lt;idref 
bean=&quot;formComponentInterceptorFactory&quot;/&gt;&lt;/property&gt;
- *   &lt;/bean&gt;
+ *       &lt;bean id=&quot;applicationServices&quot;
+ *           
class=&quot;org.springframework.richclient.application.support.DefaultApplicationServices&quot;&gt;
+ *           &lt;property 
name=&quot;applicationObjectConfigurerId&quot;&gt;&lt;idref 
bean=&quot;applicationObjectConfigurer&quot; /&gt;&lt;/property&gt;
+ *           &lt;property name=&quot;imageSourceId&quot;&gt;&lt;idref 
bean=&quot;imageSource&quot;/&gt;&lt;/property&gt;
+ *           &lt;property name=&quot;rulesSourceId&quot;&gt;&lt;idref 
bean=&quot;rulesSource&quot;/&gt;&lt;/property&gt;
+ *           &lt;property name=&quot;conversionServiceId&quot;&gt;&lt;idref 
bean=&quot;conversionService&quot;/&gt;&lt;/property&gt;
+ *           &lt;property 
name=&quot;formComponentInterceptorFactoryId&quot;&gt;&lt;idref 
bean=&quot;formComponentInterceptorFactory&quot;/&gt;&lt;/property&gt;
+ *       &lt;/bean&gt;
  * </pre>
  * 
- * Note the use of the <code>refid</code> form instead of just using a string 
value.
- * This is the preferred syntax in order to avoid having misspelled bean names 
go
- * unreported.
+ * Note the use of the <code>refid</code> form instead of just using a string 
value. This is the preferred syntax in
+ * order to avoid having misspelled bean names go unreported.
  * <p>
- * When a service is requested, via [EMAIL PROTECTED] #getService(Class)}, the 
current registry of
- * service implementations is consulted. If a registry entry was made using a 
bean id,
- * this is the point at which it will be dereferenced into the actual bean 
implementation.
- * So, the bean impementation will not be referenced until it is requested.
- * <p>
- * If a service is requested that has not been registered and a default 
implementation can
- * be provided, it will be constructed at that time. Default implementations 
are provided
- * for essentially all services referenced by the platform.
+ * Which service implementation is returned by [EMAIL PROTECTED] 
#getService(Class)} will be determined through the following
+ * steps:
+ * <ol>
+ * <li>Consult the current registry of service implementations which have been 
explicitly defined through bean
+ * definition. If a registry entry was made using a bean id, this is the point 
at which it will be dereferenced into the
+ * actual bean implementation. So, the bean impementation will not be 
referenced until it is requested.</li>
+ * <li>If the service impl. is not found yet the short string name of the 
service' Java class in decapitalized
+ * JavaBeans property format will be used to lookup the service implementation 
in the current application context.<br/>
+ * If the service class is 
<code>org.springframework.richclient.factory.MenuFactory</code> the bean name
+ * <code>menuFactory</code> will be used to find the bean</li>
+ * <li>If the service impl. is not found yet and a default implementation can 
be provided, it will be constructed at
+ * that time. Default implementations are provided for essentially all 
services referenced by the platform.</li>
+ * </ol>
  * 
  * @author Larry Streepy
  */
@@ -172,10 +176,13 @@
         Assert.required( serviceType, "serviceType" );
         Object service = services.get( serviceType );
         if( service == null ) {
-            service = getDefaultImplementation( serviceType );
-            if( service != null ) {
-                services.put( serviceType, service );
+            service = getServiceForClassType(serviceType);
+            if (service == null) {
+                service = getDefaultImplementation(serviceType);
             }
+            if (service != null) {
+                services.put(serviceType, service);
+            }
         } else {
             // Runtime derefence of refid's
             if( service instanceof String ) {
@@ -193,7 +200,7 @@
 
     public boolean containsService( Class serviceType ) {
         Assert.required( serviceType, "serviceType" );
-        return services.containsKey( serviceType ) || 
containsDefaultImplementation( serviceType );
+        return services.containsKey( serviceType ) || 
containsServiceForClassType(serviceType) || containsDefaultImplementation( 
serviceType );
     }
 
     /**
@@ -684,6 +691,36 @@
     }
 
     /**
+     * Get the implementation of a service by using the decapitalized 
shortname of the serviceType class name.
+     * 
+     * @param serviceType
+     *            the service class to lookup the bean definition
+     * @return the found service implementation if a bean definition can be 
found and it implements the required service
+     *         type, otherwise null
+     * @see ClassUtils#getShortNameAsProperty(Class)
+     */
+    protected Object getServiceForClassType(Class serviceType) {
+        String lookupName = ClassUtils.getShortNameAsProperty(serviceType);
+        ApplicationContext ctx = getApplicationContext();
+        if (ctx.containsBean(lookupName)) {
+            Object bean = ctx.getBean(lookupName);
+            if (serviceType.isAssignableFrom(bean.getClass())) {
+                if(logger.isDebugEnabled()) {
+                    logger.debug("Using bean '" + lookupName + "' (" + 
bean.getClass().getName() + ") for service " + serviceType.getName());
+                }
+                return bean;
+            }
+            else if(logger.isDebugEnabled()){
+                logger.debug("Bean with id '" + lookupName + "' (" + 
bean.getClass().getName() + ") does not implement " + serviceType.getName());
+            }
+        } else if(logger.isDebugEnabled()){
+            logger.debug("No Bean with id '" + lookupName + "' found for 
service " + serviceType.getName());
+        }
+        return null;
+    }
+
+
+    /**
      * Get the default implementation of a service according to the service 
type. If no
      * default implementation is available, then a null is returned.
      * 
@@ -700,6 +737,17 @@
     }
 
     /**
+     * Tests if the application context contains a bean definition by using 
the decapitalized shortname of the serviceType class name
+     * @param serviceType the service class to lookup the bean definition
+     * @return true if a bean definition is found in the current application 
context, otherwise false
+     * 
+     * @see ClassUtils#getShortNameAsProperty(Class)
+     */
+    protected boolean containsServiceForClassType(Class serviceType) {
+        return 
getApplicationContext().containsBean(ClassUtils.getShortNameAsProperty(serviceType));
+    }
+
+    /**
      * Tests if a default implementation for the requested service type is 
available
      * 
      * @param serviceType the requested service type


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
spring-rich-c-cvs mailing list
spring-rich-c-cvs@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/spring-rich-c-cvs

Reply via email to