You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2007/01/25 01:52:15 UTC

svn commit: r499631 - in /tapestry/tapestry5/tapestry-core/trunk/src: main/java/org/apache/tapestry/ main/java/org/apache/tapestry/corelib/components/ main/java/org/apache/tapestry/internal/services/ main/java/org/apache/tapestry/internal/structure/ te...

Author: hlship
Date: Wed Jan 24 16:52:14 2007
New Revision: 499631

URL: http://svn.apache.org/viewvc?view=rev&rev=499631
Log:
Add support for a PageLink component, and the ability to as a ComponentResources to generate a link to a page (by logical page name).

Added:
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/PageLink.java
Modified:
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentResourcesCommon.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/ActionLink.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InternalModule.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/LinkFactory.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/LinkFactoryImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/Page.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/PageImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/FlashDemo.html
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/LinkFactoryImplTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/NoOpPage.java

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentResourcesCommon.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentResourcesCommon.java?view=diff&rev=499631&r1=499630&r2=499631
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentResourcesCommon.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentResourcesCommon.java Wed Jan 24 16:52:14 2007
@@ -54,6 +54,11 @@
     Link createActionLink(String action, boolean forForm, Object... context);
 
     /**
+     * Creates a link that will case a page within the application to render.
+     */
+    Link createPageLink(String pageName);
+
+    /**
      * Returns a string consisting of the fully qualified class name of the containing page, and the
      * {@link #getNestedId() nested id} of this component, separated by a colon. I.e.,
      * "com.foo.pages.MyPage:foo.bar.baz". For a page, returns just the page class name.

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/ActionLink.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/ActionLink.java?view=diff&rev=499631&r1=499630&r2=499631
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/ActionLink.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/ActionLink.java Wed Jan 24 16:52:14 2007
@@ -66,7 +66,7 @@
 
         writer.element("a", "href", link, "id", clientId);
 
-        // TODO: Support for informal parameters, etc.
+        _resources.renderInformalParameters(writer);
     }
 
     @AfterRender

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/PageLink.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/PageLink.java?view=auto&rev=499631
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/PageLink.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/PageLink.java Wed Jan 24 16:52:14 2007
@@ -0,0 +1,60 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.Link;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.annotations.AfterRender;
+import org.apache.tapestry.annotations.BeginRender;
+import org.apache.tapestry.annotations.ComponentClass;
+import org.apache.tapestry.annotations.Environmental;
+import org.apache.tapestry.annotations.Inject;
+import org.apache.tapestry.annotations.Parameter;
+import org.apache.tapestry.services.PageRenderSupport;
+
+/**
+ * Generates a link to some other page in the application.
+ */
+@ComponentClass
+public class PageLink
+{
+    @Parameter(required = true, defaultPrefix = "literal")
+    private String _page;
+
+    @Inject
+    private ComponentResources _resources;
+
+    @Environmental
+    private PageRenderSupport _support;
+
+    @BeginRender
+    void begin(MarkupWriter writer)
+    {
+        String clientId = _support.allocateClientId(_resources.getId());
+
+        Link link = _resources.createPageLink(_page);
+
+        writer.element("a", "href", link, "id", clientId);
+
+        _resources.renderInformalParameters(writer);
+    }
+
+    @AfterRender
+    void end(MarkupWriter writer)
+    {
+        writer.end(); // <a>
+    }
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InternalModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InternalModule.java?view=diff&rev=499631&r1=499630&r2=499631
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InternalModule.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InternalModule.java Wed Jan 24 16:52:14 2007
@@ -94,6 +94,8 @@
 
     private final RequestGlobals _requestGlobals;
 
+    private final RequestPageCache _pageCache;
+
     public InternalModule(@InjectService("ComponentInstantiatorSource")
     ComponentInstantiatorSource componentInstantiatorSource, @InjectService("UpdateListenerHub")
     UpdateListenerHub updateListenerHub, @InjectService("tapestry.ioc.ThreadCleanupHub")
@@ -106,7 +108,8 @@
             Request request, @Inject("infrastructure:Response")
             Response response, @InjectService("tapestry.ioc.ThreadLocale")
             ThreadLocale threadLocale, @Inject("infrastructure:RequestGlobals")
-            RequestGlobals requestGlobals)
+            RequestGlobals requestGlobals, @InjectService("RequestPageCache")
+            RequestPageCache pageCache)
     {
         _componentInstantiatorSource = componentInstantiatorSource;
         _updateListenerHub = updateListenerHub;
@@ -118,6 +121,7 @@
         _response = response;
         _threadLocale = threadLocale;
         _requestGlobals = requestGlobals;
+        _pageCache = pageCache;
     }
 
     public ComponentClassTransformer buildComponentClassTransformer(
@@ -510,11 +514,10 @@
     }
 
     public RequestExceptionHandler buildDefaultRequestExceptionHandler(
-            @InjectService("RequestPageCache")
-            RequestPageCache pageCache, @InjectService("PageResponseRenderer")
+            @InjectService("PageResponseRenderer")
             PageResponseRenderer renderer)
     {
-        return new DefaultRequestExceptionHandler(pageCache, renderer, _response);
+        return new DefaultRequestExceptionHandler(_pageCache, renderer, _response);
     }
 
     /** Service used to create links for components and pages. */
@@ -524,7 +527,7 @@
     ComponentInvocationMap componentInvocationMap)
     {
         return new LinkFactoryImpl(contextPathSource, encoder, _componentClassResolver,
-                componentInvocationMap);
+                componentInvocationMap, _pageCache);
     }
 
     public ContextPathSource buildContextPathSource()

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/LinkFactory.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/LinkFactory.java?view=diff&rev=499631&r1=499630&r2=499631
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/LinkFactory.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/LinkFactory.java Wed Jan 24 16:52:14 2007
@@ -51,5 +51,8 @@
      */
     Link createPageLink(Page page);
 
+    /** Creates a link to a page, given its logical page name. */
+    Link createPageLink(String page);
+
     void addListener(LinkFactoryListener listener);
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/LinkFactoryImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/LinkFactoryImpl.java?view=diff&rev=499631&r1=499630&r2=499631
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/LinkFactoryImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/LinkFactoryImpl.java Wed Jan 24 16:52:14 2007
@@ -42,6 +42,8 @@
 
     private final ComponentInvocationMap _componentInvocationMap;
 
+    private final RequestPageCache _pageCache;
+
     private final List<LinkFactoryListener> _listeners = newThreadSafeList();
 
     private final StrategyRegistry<PassivateContextHandler> _registry;
@@ -53,12 +55,13 @@
 
     public LinkFactoryImpl(ContextPathSource contextPathSource, URLEncoder encoder,
             ComponentClassResolver componentClassResolver,
-            ComponentInvocationMap componentInvocationMap)
+            ComponentInvocationMap componentInvocationMap, RequestPageCache pageCache)
     {
         _contextPathSource = contextPathSource;
         _encoder = encoder;
         _componentClassResolver = componentClassResolver;
         _componentInvocationMap = componentInvocationMap;
+        _pageCache = pageCache;
 
         Map<Class, PassivateContextHandler> registrations = newMap();
 
@@ -119,8 +122,7 @@
         for (LinkFactoryListener listener : _listeners)
             listener.createdActionLink(link);
 
-        // TODO: Much more: query parameter for case where active page != component page.
-        // Letting listeners add extra parameters.
+        // TODO: query parameter for case where active page != component page.
 
         return link;
     }
@@ -161,9 +163,16 @@
         for (LinkFactoryListener listener : _listeners)
             listener.createdPageLink(link);
 
-        // TODO: Much more: query parameter for case where active page != component page.
-        // Letting listeners add extra parameters.
+        // TODO: query parameter for case where active page != component page.
 
         return link;
+    }
+
+    public Link createPageLink(String pageName)
+    {
+        // This verifies that the page name is valid.
+        Page page = _pageCache.get(pageName);
+
+        return createPageLink(page);
     }
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java?view=diff&rev=499631&r1=499630&r2=499631
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java Wed Jan 24 16:52:14 2007
@@ -772,11 +772,16 @@
     /**
      * Delegates to the
      * {@link Page#createActionLink(Element, ComponentPageElement, String, boolean, Object[]) the containing page}.
-     * Why the extra layer? Because
+     * Why the extra layer? Trying to avoid some unwanted injection (of LinkFactory, into every component page element).
      */
     public Link createActionLink(String action, boolean forForm, Object... context)
     {
         return _page.createActionLink(this, action, forForm, context);
+    }
+
+    public Link createPageLink(String pageName)
+    {
+        return _page.createPageLink(pageName);
     }
 
     public void enqueueBeforeRenderBody(RenderQueue queue)

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java?view=diff&rev=499631&r1=499630&r2=499631
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java Wed Jan 24 16:52:14 2007
@@ -109,6 +109,11 @@
         return _element.createActionLink(action, forForm, context);
     }
 
+    public Link createPageLink(String pageName)
+    {
+        return _element.createPageLink(pageName);
+    }
+
     public String getCompleteId()
     {
         return _element.getCompleteId();

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/Page.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/Page.java?view=diff&rev=499631&r1=499630&r2=499631
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/Page.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/Page.java Wed Jan 24 16:52:14 2007
@@ -124,6 +124,9 @@
     Link createActionLink(ComponentPageElement element, String action, boolean forForm,
             Object... context);
 
+    /** Creates a link to the named page. */
+    Link createPageLink(String pageName);
+
     /**
      * Posts a change to a persistent field.
      * 

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/PageImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/PageImpl.java?view=diff&rev=499631&r1=499630&r2=499631
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/PageImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/PageImpl.java Wed Jan 24 16:52:14 2007
@@ -153,6 +153,12 @@
         return _linkFactory.createActionLink(element, action, forForm, context);
     }
 
+    
+    public Link createPageLink(String pageName)
+    {
+        return _linkFactory.createPageLink(pageName);
+    }
+
     public void persistFieldChange(ComponentResources resources, String fieldName, Object newValue)
     {
         _persistentFieldManager.postChange(_name, resources, fieldName, newValue);

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/FlashDemo.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/FlashDemo.html?view=diff&rev=499631&r1=499630&r2=499631
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/FlashDemo.html (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/FlashDemo.html Wed Jan 24 16:52:14 2007
@@ -11,7 +11,7 @@
     </p>
     
     <p>
-        Click <a id="refresh" href="FlashDemo.html">here</a> to refresh the page.  Boy do we need a PageLink component!
+        Click <a t:id="refresh" t:type="PageLink" page="FlashDemo">here</a> to refresh the page. 
     </p>
 
     

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/LinkFactoryImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/LinkFactoryImplTest.java?view=diff&rev=499631&r1=499630&r2=499631
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/LinkFactoryImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/LinkFactoryImplTest.java Wed Jan 24 16:52:14 2007
@@ -136,7 +136,7 @@
 
         replay();
 
-        LinkFactory factory = new LinkFactoryImpl(request, response, resolver, map);
+        LinkFactory factory = new LinkFactoryImpl(request, response, resolver, map, null);
         factory.addListener(listener);
 
         Link link = factory.createPageLink(page);
@@ -151,6 +151,91 @@
     }
 
     @SuppressWarnings("unchecked")
+    @Test
+    public void page_link_by_name()
+    {
+        Request request = newRequest();
+        Response response = newResponse();
+        ComponentClassResolver resolver = newComponentClassResolver();
+        Page page = newPage();
+        ComponentPageElement rootElement = newComponentPageElement();
+        LinkFactoryListener listener = newLinkFactoryListener();
+        ComponentInvocationMap map = newComponentInvocationMap();
+        RequestPageCache cache = newRequestPageCache();
+
+        final Holder<Link> holder = new Holder<Link>();
+
+        train_get(cache, PAGE_LOGICAL_NAME, page);
+
+        train_getName(page, PAGE_CLASS_NAME);
+        train_resolvePageClassNameToPageName(resolver, PAGE_CLASS_NAME, PAGE_LOGICAL_NAME);
+        train_getContextPath(request, "/barney");
+
+        train_getRootElement(page, rootElement);
+
+        // Answer for triggerEvent() which returns a boolean.
+
+        IAnswer<Boolean> triggerEventAnswer = new IAnswer<Boolean>()
+        {
+            public Boolean answer() throws Throwable
+            {
+                ComponentEventHandler handler = (ComponentEventHandler) EasyMock
+                        .getCurrentArguments()[2];
+
+                handler.handleResult(new Object[]
+                { "foo", "bar" }, null, null);
+
+                return true;
+            }
+        };
+
+        IAnswer<Void> createdPageLinkAnswer = new IAnswer<Void>()
+        {
+            public Void answer() throws Throwable
+            {
+                Link link = (Link) EasyMock.getCurrentArguments()[0];
+
+                holder.put(link);
+
+                return null;
+            }
+        };
+
+        // Intercept the call to handle component event, and let the IAnswer
+        // do the work.
+
+        expect(
+                rootElement.triggerEvent(
+                        EasyMock.eq(TapestryConstants.PASSIVATE_EVENT),
+                        (Object[]) EasyMock.isNull(),
+                        EasyMock.isA(ComponentEventHandler.class))).andAnswer(triggerEventAnswer);
+
+        train_encodeRedirectURL(response, "/barney/" + PAGE_LOGICAL_NAME + ".html/foo/bar", ENCODED);
+
+        listener.createdPageLink(EasyMock.isA(Link.class));
+        getMocksControl().andAnswer(createdPageLinkAnswer);
+
+        // This needs to be refactored a bit to be more testable.
+
+        map.store(isA(Link.class), isA(ComponentInvocation.class));
+
+        replay();
+
+        LinkFactory factory = new LinkFactoryImpl(request, response, resolver, map, cache);
+        factory.addListener(listener);
+
+        Link link = factory.createPageLink(PAGE_LOGICAL_NAME);
+
+        assertEquals(link.toRedirectURI(), ENCODED);
+
+        // Make sure the link was passed to the LinkFactoryListener
+
+        assertSame(link, holder.get());
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
     private void run(String pageClassName, String logicalPageName, String nestedId,
             String contextPath, String expectedURI, Object... context)
     {
@@ -193,7 +278,7 @@
 
         replay();
 
-        LinkFactory factory = new LinkFactoryImpl(request, response, resolver, map);
+        LinkFactory factory = new LinkFactoryImpl(request, response, resolver, map, null);
         factory.addListener(listener);
 
         Link link = factory.createActionLink(element, "someaction", false, context);

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/NoOpPage.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/NoOpPage.java?view=diff&rev=499631&r1=499630&r2=499631
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/NoOpPage.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/NoOpPage.java Wed Jan 24 16:52:14 2007
@@ -98,8 +98,7 @@
         return null;
     }
 
-    public void persistFieldChange(ComponentResources resources, String fieldName,
-            Object newValue)
+    public void persistFieldChange(ComponentResources resources, String fieldName, Object newValue)
     {
     }
 
@@ -116,6 +115,11 @@
     public void decrementDirtyCount()
     {
 
+    }
+
+    public Link createPageLink(String pageName)
+    {
+        return null;
     }
 
 }