You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2005/09/16 16:31:38 UTC

svn commit: r289561 - in /jakarta/tapestry/trunk: ./ framework/src/java/org/apache/tapestry/bean/ framework/src/java/org/apache/tapestry/services/ framework/src/java/org/apache/tapestry/services/impl/ framework/src/test/org/apache/tapestry/bean/ src/do...

Author: hlship
Date: Fri Sep 16 07:31:30 2005
New Revision: 289561

URL: http://svn.apache.org/viewcvs?rev=289561&view=rev
Log:
TAPESTRY-349: Search path for managed bean classes

Added:
    jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/bean/InstantiateFailureBean.java
Modified:
    jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/bean/BeanMessages.java
    jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/bean/BeanProvider.java
    jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/bean/BeanStrings.properties
    jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/services/Infrastructure.java
    jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/services/impl/InfrastructureImpl.java
    jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/bean/TestBeanProvider.java
    jakarta/tapestry/trunk/src/documentation/content/xdocs/UsersGuide/configuration.xml
    jakarta/tapestry/trunk/status.xml

Modified: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/bean/BeanMessages.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/bean/BeanMessages.java?rev=289561&r1=289560&r2=289561&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/bean/BeanMessages.java (original)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/bean/BeanMessages.java Fri Sep 16 07:31:30 2005
@@ -35,11 +35,11 @@
         return _formatter.format("bean-not-defined", component.getExtendedId(), name);
     }
 
-    static String instantiationError(String name, IComponent component, String className,
+    static String instantiationError(String name, IComponent component, Class beanClass,
             Throwable cause)
     {
         return _formatter.format("instantiation-error", new Object[]
-        { name, component.getExtendedId(), className, cause });
+        { name, component.getExtendedId(), beanClass.getName(), cause });
     }
 
     static String initializationError(IComponent component, String beanName, String propertyName,
@@ -47,5 +47,12 @@
     {
         return _formatter.format("initialization-error", new Object[]
         { propertyName, beanName, component.getExtendedId(), cause });
+    }
+
+    static String missingBeanClass(IComponent component, String beanName, String className,
+            String packageList)
+    {
+        return _formatter.format("missing-bean-class", new Object[]
+        { beanName, component.getExtendedId(), className, packageList });
     }
 }

Modified: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/bean/BeanProvider.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/bean/BeanProvider.java?rev=289561&r1=289560&r2=289561&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/bean/BeanProvider.java (original)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/bean/BeanProvider.java Fri Sep 16 07:31:30 2005
@@ -29,10 +29,12 @@
 import org.apache.hivemind.ClassResolver;
 import org.apache.tapestry.IBeanProvider;
 import org.apache.tapestry.IComponent;
-import org.apache.tapestry.IEngine;
+import org.apache.tapestry.INamespace;
 import org.apache.tapestry.event.PageDetachListener;
 import org.apache.tapestry.event.PageEndRenderListener;
 import org.apache.tapestry.event.PageEvent;
+import org.apache.tapestry.services.ClassFinder;
+import org.apache.tapestry.services.Infrastructure;
 import org.apache.tapestry.spec.BeanLifecycle;
 import org.apache.tapestry.spec.IBeanSpecification;
 import org.apache.tapestry.spec.IComponentSpecification;
@@ -65,13 +67,21 @@
      * The component for which beans are being created and tracked.
      */
 
-    private IComponent _component;
+    private final IComponent _component;
 
     /**
      * Used for instantiating classes.
      */
 
-    private ClassResolver _resolver;
+    private final ClassResolver _resolver;
+
+    /**
+     * Used for resolving partial class names.
+     */
+
+    private final ClassFinder _classFinder;
+
+    private final String _packageList;
 
     /**
      * Map of beans, keyed on name.
@@ -90,12 +100,15 @@
     public BeanProvider(IComponent component)
     {
         _component = component;
-        IEngine engine = component.getPage().getEngine();
-        _resolver = engine.getClassResolver();
 
-        if (LOG.isDebugEnabled())
-            LOG.debug("Created BeanProvider for " + component);
+        Infrastructure infrastructure = component.getPage().getRequestCycle().getInfrastructure();
+
+        _resolver = infrastructure.getClassResolver();
+
+        INamespace namespace = component.getNamespace();
+        _packageList = namespace.getPropertyValue("org.apache.tapestry.bean-class-packages");
 
+        _classFinder = infrastructure.getClassFinder();
     }
 
     /** @since 1.0.6 * */
@@ -184,12 +197,19 @@
         if (LOG.isDebugEnabled())
             LOG.debug("Instantiating instance of " + className);
 
+        Class beanClass = _classFinder.findClass(_packageList, className);
+
+        if (beanClass == null)
+            throw new ApplicationRuntimeException(BeanMessages.missingBeanClass(
+                    _component,
+                    beanName,
+                    className,
+                    _packageList), _component, spec.getLocation(), null);
+
         // Do it the hard way!
 
         try
         {
-            Class beanClass = _resolver.findClass(className);
-
             bean = beanClass.newInstance();
         }
         catch (Exception ex)
@@ -197,7 +217,7 @@
             throw new ApplicationRuntimeException(BeanMessages.instantiationError(
                     beanName,
                     _component,
-                    className,
+                    beanClass,
                     ex), _component, spec.getLocation(), ex);
         }
 

Modified: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/bean/BeanStrings.properties
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/bean/BeanStrings.properties?rev=289561&r1=289560&r2=289561&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/bean/BeanStrings.properties (original)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/bean/BeanStrings.properties Fri Sep 16 07:31:30 2005
@@ -15,4 +15,5 @@
 property-initializer-name=initializer of property {0}
 bean-not-defined=Component {0} does not define a bean name {1}.
 instantiation-error=Unable to instantiate bean ''{0}'' (for component {1}) as class {2}: {3}
-initialization-error=Error initializing property {0} of bean ''{1}'' (of component {2}): {3}
\ No newline at end of file
+initialization-error=Error initializing property {0} of bean ''{1}'' (of component {2}): {3}
+missing-bean-class=Unable to instantiate bean ''{0}'' of component {1}: Unable to find class {2} within package list ''{3}''.
\ No newline at end of file

Modified: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/services/Infrastructure.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/services/Infrastructure.java?rev=289561&r1=289560&r2=289561&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/services/Infrastructure.java (original)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/services/Infrastructure.java Fri Sep 16 07:31:30 2005
@@ -288,4 +288,10 @@
      */
 
     public CookieSource getCookieSource();
+
+    /**
+     * Used to search for a class name within a list of packages.
+     */
+
+    public ClassFinder getClassFinder();
 }

Modified: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/services/impl/InfrastructureImpl.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/services/impl/InfrastructureImpl.java?rev=289561&r1=289560&r2=289561&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/services/impl/InfrastructureImpl.java (original)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/services/impl/InfrastructureImpl.java Fri Sep 16 07:31:30 2005
@@ -41,6 +41,7 @@
 import org.apache.tapestry.listener.ListenerInvoker;
 import org.apache.tapestry.listener.ListenerMapSource;
 import org.apache.tapestry.markup.MarkupWriterSource;
+import org.apache.tapestry.services.ClassFinder;
 import org.apache.tapestry.services.ComponentMessagesSource;
 import org.apache.tapestry.services.ComponentPropertySource;
 import org.apache.tapestry.services.CookieSource;
@@ -266,10 +267,15 @@
     {
         return (AssetFactory) getProperty("assetFactory");
     }
-    
+
     public CookieSource getCookieSource()
     {
         return (CookieSource) getProperty("cookieSource");
+    }
+
+    public ClassFinder getClassFinder()
+    {
+        return (ClassFinder) getProperty("classFinder");
     }
 
     public Object getProperty(String propertyName)

Added: jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/bean/InstantiateFailureBean.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/bean/InstantiateFailureBean.java?rev=289561&view=auto
==============================================================================
--- jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/bean/InstantiateFailureBean.java (added)
+++ jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/bean/InstantiateFailureBean.java Fri Sep 16 07:31:30 2005
@@ -0,0 +1,16 @@
+package org.apache.tapestry.bean;
+
+/**
+ * Used by {@link org.apache.tapestry.bean.TestBeanProvider} to check logic that reports errors
+ * instantiating beans.
+ * 
+ * @author Howard M. Lewis Ship
+ */
+public class InstantiateFailureBean
+{
+
+    public InstantiateFailureBean()
+    {
+        throw new RuntimeException("Boom!");
+    }
+}

Modified: jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/bean/TestBeanProvider.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/bean/TestBeanProvider.java?rev=289561&r1=289560&r2=289561&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/bean/TestBeanProvider.java (original)
+++ jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/bean/TestBeanProvider.java Fri Sep 16 07:31:30 2005
@@ -21,8 +21,11 @@
 import org.apache.tapestry.BaseComponentTestCase;
 import org.apache.tapestry.IBeanProvider;
 import org.apache.tapestry.IComponent;
-import org.apache.tapestry.IEngine;
+import org.apache.tapestry.INamespace;
 import org.apache.tapestry.IPage;
+import org.apache.tapestry.IRequestCycle;
+import org.apache.tapestry.services.ClassFinder;
+import org.apache.tapestry.services.Infrastructure;
 import org.apache.tapestry.spec.BeanSpecification;
 import org.apache.tapestry.spec.IBeanSpecification;
 
@@ -63,15 +66,14 @@
         getControl(spec).setReturnValue(className);
     }
 
-    public void testInstantiateFailure()
+    public void testResolveClassFailure()
     {
         ClassResolver resolver = newResolver();
-        IEngine engine = newEngine(resolver);
         IPage page = newPage();
         IComponent component = newComponent();
+        ClassFinder finder = newClassFinder();
 
-        trainGetPage(component, page);
-        trainGetEngine(page, engine);
+        trainForConstructor(page, component, resolver, finder);
 
         replayControls();
 
@@ -83,10 +85,53 @@
 
         trainGetClassName(bs, "org.foo.Bar");
 
-        Throwable t = new RuntimeException("Poof!");
+        trainFindClass(finder, "org.foo.Bar", null);
+
+        trainGetExtendedId(component, "Fred/barney");
+
+        Location l = newLocation();
+
+        trainGetLocation(bs, l);
+
+        replayControls();
+
+        try
+        {
+            bp.instantiateBean("wilma", bs);
+            unreachable();
+        }
+        catch (ApplicationRuntimeException ex)
+        {
+            assertEquals(
+                    "Unable to instantiate bean 'wilma' of component Fred/barney: Unable to find class org.foo.Bar within package list 'mypackage'.",
+                    ex.getMessage());
+            assertSame(component, ex.getComponent());
+            assertSame(l, ex.getLocation());
+        }
+
+        verifyControls();
+    }
+
+    public void testInstantiateBeanFailure()
+    {
+        ClassResolver resolver = newResolver();
+        IPage page = newPage();
+        IComponent component = newComponent();
+        ClassFinder finder = newClassFinder();
+
+        trainForConstructor(page, component, resolver, finder);
 
-        resolver.findClass("org.foo.Bar");
-        getControl(resolver).setThrowable(t);
+        replayControls();
+
+        BeanProvider bp = new BeanProvider(component);
+
+        verifyControls();
+
+        IBeanSpecification bs = newBeanSpec();
+
+        trainGetClassName(bs, "org.foo.Bar");
+
+        trainFindClass(finder, "org.foo.Bar", InstantiateFailureBean.class);
 
         trainGetExtendedId(component, "Fred/barney");
 
@@ -104,16 +149,48 @@
         catch (ApplicationRuntimeException ex)
         {
             assertEquals(
-                    "Unable to instantiate bean 'wilma' (for component Fred/barney) as class org.foo.Bar: Poof!",
+                    "Unable to instantiate bean 'wilma' (for component Fred/barney) as class org.apache.tapestry.bean.InstantiateFailureBean: Boom!",
                     ex.getMessage());
             assertSame(component, ex.getComponent());
             assertSame(l, ex.getLocation());
-            assertSame(t, ex.getRootCause());
         }
 
         verifyControls();
     }
 
+    private void trainForConstructor(IPage page, IComponent component, ClassResolver resolver,
+            ClassFinder classFinder)
+    {
+        IRequestCycle cycle = newCycle();
+        Infrastructure infrastructure = (Infrastructure) newMock(Infrastructure.class);
+        INamespace namespace = (INamespace) newMock(INamespace.class);
+
+        trainGetPage(component, page);
+
+        page.getRequestCycle();
+        getControl(page).setReturnValue(cycle);
+
+        cycle.getInfrastructure();
+        getControl(cycle).setReturnValue(infrastructure);
+
+        infrastructure.getClassResolver();
+        getControl(infrastructure).setReturnValue(resolver);
+
+        component.getNamespace();
+        getControl(component).setReturnValue(namespace);
+
+        namespace.getPropertyValue("org.apache.tapestry.bean-class-packages");
+        getControl(namespace).setReturnValue("mypackage");
+
+        infrastructure.getClassFinder();
+        getControl(infrastructure).setReturnValue(classFinder);
+    }
+
+    protected ClassFinder newClassFinder()
+    {
+        return (ClassFinder) newMock(ClassFinder.class);
+    }
+
     private ClassResolver newResolver()
     {
         return (ClassResolver) newMock(ClassResolver.class);
@@ -122,12 +199,11 @@
     public void testInitializeFailure()
     {
         ClassResolver resolver = new DefaultClassResolver();
-        IEngine engine = newEngine(resolver);
         IPage page = newPage();
         IComponent component = newComponent();
+        ClassFinder finder = newClassFinder();
 
-        trainGetPage(component, page);
-        trainGetEngine(page, engine);
+        trainForConstructor(page, component, resolver, finder);
 
         replayControls();
 
@@ -135,8 +211,12 @@
 
         verifyControls();
 
+        String className = TargetBean.class.getName();
+
+        trainFindClass(finder, className, TargetBean.class);
+
         IBeanSpecification spec = new BeanSpecification();
-        spec.setClassName(TargetBean.class.getName());
+        spec.setClassName(className);
 
         RuntimeException t = new RuntimeException("Blat!");
 
@@ -166,5 +246,11 @@
             assertSame(t, ex.getRootCause());
         }
 
+    }
+
+    private void trainFindClass(ClassFinder finder, String className, Class clazz)
+    {
+        finder.findClass("mypackage", className);
+        getControl(finder).setReturnValue(clazz);
     }
 }

Modified: jakarta/tapestry/trunk/src/documentation/content/xdocs/UsersGuide/configuration.xml
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/src/documentation/content/xdocs/UsersGuide/configuration.xml?rev=289561&r1=289560&r2=289561&view=diff
==============================================================================
--- jakarta/tapestry/trunk/src/documentation/content/xdocs/UsersGuide/configuration.xml (original)
+++ jakarta/tapestry/trunk/src/documentation/content/xdocs/UsersGuide/configuration.xml Fri Sep 16 07:31:30 2005
@@ -335,6 +335,15 @@
   </tr>
   
   <tr>
+    <td>org.apache.tapestry.bean-class-packages</td>
+    <td>
+      A comma-seperated list, used when converting class names for managed beans (specified
+      using the &spec.bean; element) into fully qualified class names. This property is specified
+      in the containing library or application specification.
+    </td>
+  </tr>
+  
+  <tr>
   <td>org.apache.tapestry.component-class-packages</td>
   <td>
     A comma-seperated list of package names, used when

Modified: jakarta/tapestry/trunk/status.xml
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/status.xml?rev=289561&r1=289560&r2=289561&view=diff
==============================================================================
--- jakarta/tapestry/trunk/status.xml (original)
+++ jakarta/tapestry/trunk/status.xml Fri Sep 16 07:31:30 2005
@@ -69,6 +69,7 @@
       <action type="fix" dev="HLS" fixes-bug="TAPESTRY-579">Using component types with slashes in the HTML template fails</action>
       <action type="fix" dev="HLS" fixes-bug="TAPESTRY-595">Resource prefixes not honored inside &lt;page&gt;'s specification-path attribute</action>
       <action type="fix" dev="HLS" fixes-bug="TAPESTRY-569">WebResponse does not expose a way to set headers</action>
+      <action type="fix" dev="HLS" fixes-bug="TAPESTRY-349">Search path for managed bean classes</action>
     </release>
     <release version="4.0-beta-6" date="Sep 7 2005">
       <action type="update" dev="HLS" due-to="Henri Yandell">Convert Tapestry repository from CVS to SVN</action>



---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org