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 2006/08/25 03:30:28 UTC

svn commit: r434590 - in /tapestry/tapestry5/tapestry-core/trunk: .settings/ src/ src/main/java/org/apache/tapestry/ src/main/java/org/apache/tapestry/internal/services/ src/main/java/org/apache/tapestry/internal/structure/ src/main/java/org/apache/tap...

Author: hlship
Date: Thu Aug 24 18:30:27 2006
New Revision: 434590

URL: http://svn.apache.org/viewvc?rev=434590&view=rev
Log:
Check point some changes preparing to get minimal page rendering working.
Create a yEd diagram of the component render state machine.

Added:
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentClassResolverImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageResponseRendererImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RenderQueueImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RequestPageCache.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RequestPageCacheImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/RenderCommand.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/RenderQueue.java
    tapestry/tapestry5/tapestry-core/trunk/src/render-states.ygf   (with props)
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/PagePoolImplTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/RequestPageCacheImplTest.java
Modified:
    tapestry/tapestry5/tapestry-core/trunk/.settings/org.eclipse.jdt.ui.prefs
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/TapestryFilter.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/HTMLDispatcher.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/PageElementFactoryImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PagePoolImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageResponseRenderer.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/UpdateListenerHub.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/AttributePageElement.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElement.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/Page.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/PageElement.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/PageImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/StartElementPageElement.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/TextPageElement.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/ComponentLifecycle.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/ComponentClassResolver.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/PageElementFactoryImplTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/structure/PageImplTest.java

Modified: tapestry/tapestry5/tapestry-core/trunk/.settings/org.eclipse.jdt.ui.prefs
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/.settings/org.eclipse.jdt.ui.prefs?rev=434590&r1=434589&r2=434590&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/.settings/org.eclipse.jdt.ui.prefs (original)
+++ tapestry/tapestry5/tapestry-core/trunk/.settings/org.eclipse.jdt.ui.prefs Thu Aug 24 18:30:27 2006
@@ -1,4 +1,5 @@
-#Tue Aug 01 12:05:23 PDT 2006
+#Thu Aug 24 14:16:53 PDT 2006
 eclipse.preferences.version=1
 formatter_settings_version=8
 internal.default.compliance=default
+org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8"?><templates/>

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/TapestryFilter.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/TapestryFilter.java?rev=434590&r1=434589&r2=434590&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/TapestryFilter.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/TapestryFilter.java Thu Aug 24 18:30:27 2006
@@ -29,9 +29,12 @@
 import org.apache.tapestry.ioc.Registry;
 import org.apache.tapestry.ioc.RegistryBuilder;
 import org.apache.tapestry.services.ApplicationInitializer;
+import org.apache.tapestry.services.ComponentClassResolver;
 import org.apache.tapestry.services.HttpServletRequestHandler;
 import org.apache.tapestry.services.TapestryModule;
 
+import static org.apache.tapestry.internal.ioc.IOCUtilities.capitalize;
+
 /**
  * The TapestryFilter is responsible for intercepting all requests into the web application. It
  * identifies the requests that are relevant to Tapestry, and lets the servlet container handle the
@@ -70,8 +73,7 @@
         String appPackage = _config.getInitParameter("tapestry.app-package");
         String filterName = _config.getFilterName();
 
-        String className = appPackage + ".services."
-                + org.apache.tapestry.internal.ioc.IOCUtilities.capitalize(filterName) + "Module";
+        String className = appPackage + ".services." + capitalize(filterName) + "Module";
 
         try
         {
@@ -91,6 +93,16 @@
         addModules(builder);
 
         _registry = builder.build();
+
+        // It would be nice to move this logic inside ApplicationInitializer,
+        // may have to pass in the FilterConfig, or maybe a wrapper around
+        // it.
+
+        ComponentClassResolver resolver = _registry.getService(
+                "tapestry.ComponentClassResolver",
+                ComponentClassResolver.class);
+
+        resolver.setApplicationPackage(appPackage);
 
         ApplicationInitializer ai = _registry.getService(
                 "tapestry.ApplicationInitializer",

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentClassResolverImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentClassResolverImpl.java?rev=434590&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentClassResolverImpl.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentClassResolverImpl.java Thu Aug 24 18:30:27 2006
@@ -0,0 +1,43 @@
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.services.ComponentClassResolver;
+
+/**
+ * @author Howard M. Lewis Ship
+ */
+public class ComponentClassResolverImpl implements ComponentClassResolver
+{
+    private final ComponentInstantiatorSource _componentInstantiatorSource;
+
+    public ComponentClassResolverImpl(ComponentInstantiatorSource componentInstantiatorSource)
+    {
+        _componentInstantiatorSource = componentInstantiatorSource;
+    }
+
+    private String _appPagePackage;
+
+    public String resolvePageName(String inputPageName)
+    {
+        if (inputPageName.contains("."))
+            return inputPageName;
+
+        // For now, assume it is in the application page package.
+        // So much more to do: search libraries, handle
+        // sub-dirs/sub-packages, search in the
+        // framework if not found elsewhere.
+
+        return _appPagePackage + "." + inputPageName;
+    }
+
+    public String resolveComponentName(String inputComponentName)
+    {
+        return null;
+    }
+
+    public void setApplicationPackage(String packageName)
+    {
+        _appPagePackage = packageName = ".pages";
+
+        _componentInstantiatorSource.addPackage(_appPagePackage);
+    }
+}
\ No newline at end of file

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/HTMLDispatcher.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/HTMLDispatcher.java?rev=434590&r1=434589&r2=434590&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/HTMLDispatcher.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/HTMLDispatcher.java Thu Aug 24 18:30:27 2006
@@ -14,6 +14,8 @@
 
 package org.apache.tapestry.internal.services;
 
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.services.ComponentClassResolver;
 import org.apache.tapestry.services.Dispatcher;
 import org.apache.tapestry.services.WebRequest;
 import org.apache.tapestry.services.WebResponse;
@@ -26,10 +28,41 @@
  */
 public class HTMLDispatcher implements Dispatcher
 {
+    private final ComponentClassResolver _resolver;
+
+    private final PageResponseRenderer _renderer;
+
+    private final RequestPageCache _cache;
+
+    public HTMLDispatcher(ComponentClassResolver resolver, PageResponseRenderer renderer,
+            RequestPageCache cache)
+    {
+        _resolver = resolver;
+        _renderer = renderer;
+        _cache = cache;
+    }
+
     public boolean dispatch(WebRequest request, WebResponse response)
     {
         String path = request.getPath();
 
-        return false;
+        // For the moment, just matching things that end with .html
+
+        int pos = path.indexOf(".html");
+
+        if (pos < 0)
+            return false;
+
+        // We have a match!
+
+        String minimalPageName = path.substring(0, pos);
+
+        String fullPageName = _resolver.resolvePageName(minimalPageName);
+
+        Page page = _cache.get(fullPageName);
+
+        _renderer.renderPageResponse(page, response);
+
+        return true;
     }
 }

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?rev=434590&r1=434589&r2=434590&view=diff
==============================================================================
--- 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 Thu Aug 24 18:30:27 2006
@@ -19,9 +19,11 @@
 import org.apache.tapestry.ioc.annotations.Contribute;
 import org.apache.tapestry.ioc.annotations.Id;
 import org.apache.tapestry.ioc.annotations.InjectService;
+import org.apache.tapestry.ioc.annotations.Lifecycle;
 import org.apache.tapestry.ioc.annotations.Match;
 import org.apache.tapestry.ioc.annotations.Order;
 import org.apache.tapestry.ioc.services.LoggingDecorator;
+import org.apache.tapestry.ioc.services.ThreadCleanupHub;
 import org.apache.tapestry.services.ComponentClassTransformWorker;
 
 /**
@@ -34,12 +36,16 @@
 
     private final UpdateListenerHub _updateListenerHub;
 
+    private final ThreadCleanupHub _threadCleanupHub;
+
     public InternalModule(@InjectService("ComponentInstantiatorSource")
     ComponentInstantiatorSource componentInstantiatorSource, @InjectService("UpdateListenerHub")
-    UpdateListenerHub updateListenerHub)
+    UpdateListenerHub updateListenerHub, @InjectService("tapestry.ioc.ThreadCleanupHub")
+    ThreadCleanupHub threadCleanupHub)
     {
         _componentInstantiatorSource = componentInstantiatorSource;
         _updateListenerHub = updateListenerHub;
+        _threadCleanupHub = threadCleanupHub;
     }
 
     public ComponentClassTransformer buildComponentClassTransformer(
@@ -88,9 +94,24 @@
         return service;
     }
 
+    public PagePool buildPagePool(@InjectService("PageLoader")
+    PageLoader pageLoader)
+    {
+        PagePoolImpl service = new PagePoolImpl(pageLoader);
+
+        // This covers invalidations due to changes to classes; we also
+        // need to invalidate when changes to templates occur. The TemplateLoader
+        // will ultimately be an invalidation event hub as well.
+
+        pageLoader.addInvalidationListener(service);
+
+        return service;
+    }
+
     /**
-     * The UpdateListenerHub is responsible for tracking which listeners are interested when some
-     * part of external storage changes (invalidating cached data).
+     * The UpdateListenerHub provides events that other services used to check for invalidations.
+     * Such services usually are {@link org.apache.tapestry.internal.event.InvalidationEventHub}s,
+     * and fire invalidation events to their listeners.
      */
     public UpdateListenerHub buildUpdateListenerHub()
     {
@@ -119,4 +140,14 @@
         return loggingDecorator.build(serviceInterface, delegate, serviceId, log);
     }
 
+    @Lifecycle("perthread")
+    public RequestPageCache buildRequestPageCache(@InjectService("PagePool")
+    PagePool pagePool)
+    {
+        RequestPageCacheImpl service = new RequestPageCacheImpl(pagePool);
+
+        _threadCleanupHub.addThreadCleanupListener(service);
+
+        return service;
+    }
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageElementFactoryImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageElementFactoryImpl.java?rev=434590&r1=434589&r2=434590&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageElementFactoryImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageElementFactoryImpl.java Thu Aug 24 18:30:27 2006
@@ -27,6 +27,7 @@
 import org.apache.tapestry.internal.structure.PageElement;
 import org.apache.tapestry.internal.structure.StartElementPageElement;
 import org.apache.tapestry.internal.structure.TextPageElement;
+import org.apache.tapestry.runtime.RenderQueue;
 
 /**
  * @author Howard M. Lewis Ship
@@ -43,7 +44,7 @@
     /** Singleton instance that represents any close tag of any element in any template. */
     private final PageElement _endElement = new PageElement()
     {
-        public void render(MarkupWriter writer)
+        public void render(MarkupWriter writer, RenderQueue queue)
         {
             writer.end();
         }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PagePoolImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PagePoolImpl.java?rev=434590&r1=434589&r2=434590&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PagePoolImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PagePoolImpl.java Thu Aug 24 18:30:27 2006
@@ -18,23 +18,23 @@
 import java.util.Locale;
 import java.util.Map;
 
+import org.apache.tapestry.events.InvalidationEvent;
+import org.apache.tapestry.events.InvalidationListener;
 import org.apache.tapestry.internal.structure.Page;
 import org.apache.tapestry.util.CollectionFactory;
 
 /**
  * A very naive implementation just to get us past the start line.
  * <p>
- * TODO: Clear pool on cache invalidation.
+ * Registered as an invalidation listener with the
+ * {@link org.apache.tapestry.internal.services.PageLoader}; thus the pool is cleared whenever
  * 
  * @author Howard M. Lewis Ship
  */
-public class PagePoolImpl implements PagePool
+public class PagePoolImpl implements PagePool, InvalidationListener
 {
     private final PageLoader _pageLoader;
 
-    // TODO: The key for this will ultimately be qualified with locale (or locale name) as well
-    // as page name.
-
     private final Map<String, List<Page>> _pool = CollectionFactory.newMap();
 
     public PagePoolImpl(PageLoader pageLoader)
@@ -56,7 +56,7 @@
 
     public synchronized void release(Page page)
     {
-        page.detach();
+        page.detached();
 
         String key = page.getName();
         List<Page> pages = _pool.get(key);
@@ -68,6 +68,15 @@
         }
 
         pages.add(page);
+    }
+
+    public synchronized void objectWasInvalidated(InvalidationEvent event)
+    {
+        _pool.clear();
+
+        // The synchronized is not really needed, since invalidation events are published
+        // when Tapestry is in a single-threaded mode. Because of that, we don't have to worry about
+        // some thread release()ing a page from before the invalidation event.
     }
 
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageResponseRenderer.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageResponseRenderer.java?rev=434590&r1=434589&r2=434590&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageResponseRenderer.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageResponseRenderer.java Thu Aug 24 18:30:27 2006
@@ -14,9 +14,10 @@
 
 package org.apache.tapestry.internal.services;
 
+import org.apache.tapestry.internal.structure.Page;
 import org.apache.tapestry.services.WebResponse;
 
 public interface PageResponseRenderer
 {
-    void renderPageResponse(Object page, WebResponse response);
+    void renderPageResponse(Page page, WebResponse response);
 }

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageResponseRendererImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageResponseRendererImpl.java?rev=434590&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageResponseRendererImpl.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageResponseRendererImpl.java Thu Aug 24 18:30:27 2006
@@ -0,0 +1,17 @@
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.services.MarkupWriterFactory;
+import org.apache.tapestry.services.WebResponse;
+
+public class PageResponseRendererImpl implements PageResponseRenderer
+{
+    private MarkupWriterFactory _markupWriterFactory;
+    
+    public void renderPageResponse(Page page, WebResponse response)
+    {
+
+        
+    }
+
+}

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RenderQueueImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RenderQueueImpl.java?rev=434590&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RenderQueueImpl.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RenderQueueImpl.java Thu Aug 24 18:30:27 2006
@@ -0,0 +1,32 @@
+package org.apache.tapestry.internal.services;
+
+import java.util.List;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.runtime.RenderCommand;
+import org.apache.tapestry.runtime.RenderQueue;
+
+import static org.apache.tapestry.util.CollectionFactory.newList;
+
+/**
+ * @author Howard M. Lewis Ship
+ */
+public class RenderQueueImpl implements RenderQueue
+{
+    private final List<RenderCommand> _queue = newList();
+
+    public void addFirst(RenderCommand command)
+    {
+        _queue.add(command);
+    }
+
+    public void run(MarkupWriter writer)
+    {
+        while (!_queue.isEmpty())
+        {
+            RenderCommand command = _queue.remove(_queue.size() - 1);
+
+            command.render(writer, this);
+        }
+    }
+}

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RequestPageCache.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RequestPageCache.java?rev=434590&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RequestPageCache.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RequestPageCache.java Thu Aug 24 18:30:27 2006
@@ -0,0 +1,20 @@
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.structure.Page;
+
+/**
+ * Per-thread service that caches page instances for the duration of the request.
+ * 
+ * @author Howard M. Lewis Ship
+ */
+public interface RequestPageCache
+{
+    /**
+     * Gets the page via its page name, in the current locale.
+     * 
+     * @param pageName
+     *            the FQCN of the page
+     * @return a page instance reserved for this request
+     */
+    Page get(String pageName);
+}

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RequestPageCacheImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RequestPageCacheImpl.java?rev=434590&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RequestPageCacheImpl.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RequestPageCacheImpl.java Thu Aug 24 18:30:27 2006
@@ -0,0 +1,46 @@
+package org.apache.tapestry.internal.services;
+
+import java.util.Map;
+
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.ioc.services.ThreadCleanupListener;
+
+import static org.apache.tapestry.util.CollectionFactory.newMap;
+
+/**
+ * @author Howard M. Lewis Ship
+ */
+public class RequestPageCacheImpl implements RequestPageCache, ThreadCleanupListener
+{
+    private final PagePool _pagePool;
+
+    private final Map<String, Page> _cache = newMap();
+
+    public RequestPageCacheImpl(PagePool pagePool)
+    {
+        _pagePool = pagePool;
+    }
+
+    public Page get(String pageName)
+    {
+        Page page = _cache.get(pageName);
+
+        if (page == null)
+        {
+            page = _pagePool.checkout(pageName);
+
+            page.attached();
+
+            _cache.put(pageName, page);
+        }
+
+        return page;
+    }
+
+    public void threadDidCleanup()
+    {
+        for (Page p : _cache.values())
+            _pagePool.release(p);
+    }
+
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/UpdateListenerHub.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/UpdateListenerHub.java?rev=434590&r1=434589&r2=434590&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/UpdateListenerHub.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/UpdateListenerHub.java Thu Aug 24 18:30:27 2006
@@ -17,9 +17,15 @@
 import org.apache.tapestry.events.UpdateListener;
 
 /**
- * Manages a set of {@link org.apache.tapestry.events.UpdateListener}s.
+ * Manages a set of {@link org.apache.tapestry.events.UpdateListener}s. Periodically (say, every
+ * request during development, or every minute or so during production), request processing is
+ * locked down so that only a single thread is active, and the active thread invokes
+ * {@link #fireUpdateEvent()}. Various services that are dependent on external resource files (such
+ * as classes or template files) can check to see if any file they've used has changed. If so, the
+ * service can invalidate its internal cache, or notify other services that they should do the same.
  * 
  * @author Howard M. Lewis Ship
+ * @see org.apache.tapestry.internal.util.URLChangeTracker
  */
 public interface UpdateListenerHub
 {
@@ -28,5 +34,11 @@
     /** For completeness. */
     void removeUpdateListener(UpdateListener listener);
 
+    /**
+     * Invoked periodically to allow services to check if underlying state has changed. For example,
+     * a template file may have changed. Listeners will typically notify applicable listeners of
+     * their own (they usually implement
+     * {@link org.apache.tapestry.internal.event.InvalidationEventHub}) when such a change occurs.
+     */
     void fireUpdateEvent();
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/AttributePageElement.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/AttributePageElement.java?rev=434590&r1=434589&r2=434590&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/AttributePageElement.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/AttributePageElement.java Thu Aug 24 18:30:27 2006
@@ -15,6 +15,7 @@
 package org.apache.tapestry.internal.structure;
 
 import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.runtime.RenderQueue;
 
 /**
  * A page element that renders an attribute (into the most recently started element).
@@ -33,7 +34,7 @@
         _value = value;
     }
 
-    public void render(MarkupWriter writer)
+    public void render(MarkupWriter writer, RenderQueue queue)
     {
         writer.attribute(_name, _value);
     }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElement.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElement.java?rev=434590&r1=434589&r2=434590&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElement.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElement.java Thu Aug 24 18:30:27 2006
@@ -16,6 +16,7 @@
 
 import org.apache.tapestry.internal.InternalComponentResources;
 import org.apache.tapestry.internal.parser.AttributeToken;
+import org.apache.tapestry.runtime.RenderCommand;
 
 /**
  * Extended version of {@link org.apache.tapestry.internal.structure.PageElement} for elements that
@@ -23,7 +24,7 @@
  * 
  * @author Howard M. Lewis Ship
  */
-public interface ComponentPageElement extends PageElement, InternalComponentResources
+public interface ComponentPageElement extends PageElement, InternalComponentResources, RenderCommand
 {
     /**
      * Containing component (or null for the root component of a 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?rev=434590&r1=434589&r2=434590&view=diff
==============================================================================
--- 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 Thu Aug 24 18:30:27 2006
@@ -18,9 +18,12 @@
 import java.util.Map;
 
 import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.internal.annotations.SuppressNullCheck;
 import org.apache.tapestry.internal.parser.AttributeToken;
 import org.apache.tapestry.internal.services.Instantiator;
 import org.apache.tapestry.runtime.ComponentLifecycle;
+import org.apache.tapestry.runtime.RenderCommand;
+import org.apache.tapestry.runtime.RenderQueue;
 
 import static org.apache.tapestry.util.CollectionFactory.newList;
 import static org.apache.tapestry.util.CollectionFactory.newMap;
@@ -68,7 +71,6 @@
      * Constructor for other components embedded within the root component or at deeper levels of
      * the hierarchy.
      */
-
     public ComponentPageElementImpl(Page page, ComponentPageElement container, String id,
             Instantiator instantiator)
     {
@@ -123,9 +125,82 @@
         return _id;
     }
 
-    public void render(MarkupWriter writer)
+    // NOTE: May want to investigate lazy creation of these.
+
+    // This is the state machine for rendering an individual component.
+
+    private RenderCommand _beforeRender = new RenderCommand()
+    {
+        @SuppressNullCheck
+        public void render(MarkupWriter writer, RenderQueue queue)
+        {
+            boolean render = _component.beforeRender(writer);
+
+            queue.addFirst(render ? _renderTag : _afterRender);
+        }
+    };
+
+    private RenderCommand _renderTag = new RenderCommand()
+    {
+        @SuppressNullCheck
+        public void render(MarkupWriter writer, RenderQueue queue)
+        {
+            boolean render = _component.renderTag(writer);
+
+            if (render)
+            {
+                // Push this deepeset: after rendering the template
+                // (including the render body directive), we want to
+                // give the component a chance to render its close tag.
+
+                queue.addFirst(_renderCloseTag);
+
+                // Push them in reverse order, so that the first template item
+                // it at the head of the queue.
+
+                int count = size(_template);
+                for (int i = count - 1; i >= 0; i--)
+                    queue.addFirst(_template.get(i));
+
+                // TODO: Component without template but with a body ... should probably push
+                // a _beforeRenderBody directly.
+            }
+            else
+                queue.addFirst(_afterRender);
+        }
+    };
+
+    private RenderCommand _renderCloseTag = new RenderCommand()
+    {
+        @SuppressNullCheck
+        public void render(MarkupWriter writer, RenderQueue queue)
+        {
+            boolean rerender = _component.renderCloseTag(writer);
+
+            queue.addFirst(rerender ? _renderTag : _afterRender);
+        }
+    };
+
+    private RenderCommand _afterRender = new RenderCommand()
+    {
+        @SuppressNullCheck
+        public void render(MarkupWriter writer, RenderQueue queue)
+        {
+            boolean rerender = _component.renderCloseTag(writer);
+
+            if (rerender)
+                queue.addFirst(_beforeRender);
+        }
+    };
+
+    public void render(MarkupWriter writer, RenderQueue queue)
+    {
+        queue.addFirst(_beforeRender);
+    }
+
+    private int size(List<?> list)
     {
-        throw new UnsupportedOperationException("Not yet implemented.");
+        return list == null ? 0 : list.size();
     }
 
 }

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?rev=434590&r1=434589&r2=434590&view=diff
==============================================================================
--- 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 Thu Aug 24 18:30:27 2006
@@ -57,8 +57,16 @@
      * 
      * @see ComponentLifecycle#containingPageDidDetach()
      */
-    void detach();
+    void detached();
 
+    /**
+     * Inform the page that it is attached to the current request. This occurs when a page is first referenced within
+     * a request. If the page was created for this request, the call to {@link #loaded()} will preceded the
+     * call to {@link #attached()}.
+     */
+    
+    void attached();
+    
     /**
      * Inform the page that it is now completely loaded.
      * 

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/PageElement.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/PageElement.java?rev=434590&r1=434589&r2=434590&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/PageElement.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/PageElement.java Thu Aug 24 18:30:27 2006
@@ -14,7 +14,7 @@
 
 package org.apache.tapestry.internal.structure;
 
-import org.apache.tapestry.Renderable;
+import org.apache.tapestry.runtime.RenderCommand;
 
 /**
  * An element within a page. Page elements are placeholders that delegate much of their behavior to
@@ -23,6 +23,6 @@
  * 
  * @author Howard M. Lewis Ship
  */
-public interface PageElement extends Renderable
+public interface PageElement extends RenderCommand
 {
 }

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?rev=434590&r1=434589&r2=434590&view=diff
==============================================================================
--- 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 Thu Aug 24 18:30:27 2006
@@ -63,7 +63,7 @@
         _components.add(component);
     }
 
-    public void detach()
+    public void detached()
     {
         for (ComponentLifecycle c : _components)
             c.containingPageDidDetach();
@@ -73,6 +73,11 @@
     {
         for (ComponentLifecycle c : _components)
             c.containingPageDidLoad();
+    }
+
+    public void attached()
+    {
+        // TODO: Define methods on ComponentLifecycle to invoke
     }
 
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/StartElementPageElement.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/StartElementPageElement.java?rev=434590&r1=434589&r2=434590&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/StartElementPageElement.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/StartElementPageElement.java Thu Aug 24 18:30:27 2006
@@ -15,6 +15,7 @@
 package org.apache.tapestry.internal.structure;
 
 import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.runtime.RenderQueue;
 
 /**
  * @author Howard M. Lewis Ship
@@ -28,7 +29,7 @@
         _name = name;
     }
 
-    public void render(MarkupWriter writer)
+    public void render(MarkupWriter writer, RenderQueue queue)
     {
         writer.element(_name);
     }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/TextPageElement.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/TextPageElement.java?rev=434590&r1=434589&r2=434590&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/TextPageElement.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/TextPageElement.java Thu Aug 24 18:30:27 2006
@@ -15,7 +15,11 @@
 package org.apache.tapestry.internal.structure;
 
 import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.runtime.RenderQueue;
 
+/**
+ * @author Howard M. Lewis Ship
+ */
 public class TextPageElement implements PageElement
 {
     private final String _text;
@@ -25,7 +29,7 @@
         _text = text;
     }
 
-    public void render(MarkupWriter writer)
+    public void render(MarkupWriter writer, RenderQueue queue)
     {
         writer.write(_text);
     }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java?rev=434590&r1=434589&r2=434590&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java Thu Aug 24 18:30:27 2006
@@ -15,6 +15,7 @@
 package org.apache.tapestry.internal.test;
 
 import java.util.List;
+import java.util.Locale;
 
 import org.apache.tapestry.internal.InternalComponentResources;
 import org.apache.tapestry.internal.annotations.SuppressNullCheck;
@@ -22,6 +23,9 @@
 import org.apache.tapestry.internal.ioc.Module;
 import org.apache.tapestry.internal.parser.ComponentTemplate;
 import org.apache.tapestry.internal.services.ComponentInstantiatorSource;
+import org.apache.tapestry.internal.services.PageLoader;
+import org.apache.tapestry.internal.services.PagePool;
+import org.apache.tapestry.internal.structure.Page;
 import org.apache.tapestry.ioc.ObjectProvider;
 import org.apache.tapestry.ioc.Registry;
 import org.apache.tapestry.ioc.RegistryBuilder;
@@ -30,6 +34,7 @@
 import org.apache.tapestry.ioc.ServiceLocator;
 import org.apache.tapestry.ioc.def.ServiceDef;
 import org.apache.tapestry.runtime.ComponentLifecycle;
+import org.apache.tapestry.runtime.RenderQueue;
 import org.apache.tapestry.test.BaseTestCase;
 import org.apache.tapestry.util.CollectionFactory;
 import org.easymock.EasyMock;
@@ -118,5 +123,37 @@
     protected ComponentLifecycle newComponentLifecycle()
     {
         return newMock(ComponentLifecycle.class);
+    }
+
+    protected final Page newPage()
+    {
+        return newMock(Page.class);
+    }
+
+    protected final PageLoader newPageLoader()
+    {
+        return newMock(PageLoader.class);
+    }
+
+    protected final void trainLoadPage(PageLoader loader, String pageName, Locale locale, Page page)
+    {
+        loader.loadPage(pageName, locale);
+        setReturnValue(page);
+    }
+
+    protected final void trainGetName(Page page, String name)
+    {
+        page.getName();
+        setReturnValue(name);
+    }
+
+    protected final PagePool newPagePool()
+    {
+        return newMock(PagePool.class);
+    }
+
+    protected RenderQueue newRenderQueue()
+    {
+        return newMock(RenderQueue.class);
     }
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/ComponentLifecycle.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/ComponentLifecycle.java?rev=434590&r1=434589&r2=434590&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/ComponentLifecycle.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/ComponentLifecycle.java Thu Aug 24 18:30:27 2006
@@ -14,6 +14,8 @@
 
 package org.apache.tapestry.runtime;
 
+import org.apache.tapestry.MarkupWriter;
+
 /**
  * Interface that defining the lifecycle of a component, within a page, allowing for callbacks into
  * the component for many different events. This interface is part of the public API for Tapestry,
@@ -34,4 +36,47 @@
      * client specific state.
      */
     void containingPageDidDetach();
+
+    /**
+     * Invoked before rendering a component (or its template).
+     * 
+     * @return true to procede to {@link #renderTag(MarkupWriter)}, false to skip to
+     *         {@link #afterRender(MarkupWriter)}.
+     */
+    boolean beforeRender(MarkupWriter writer);
+
+    /**
+     * Invoked to allow a component to render its tag (start tag and attributes).
+     * 
+     * @return true to render the component's template (eventually invoking
+     *         {@link #beforeRenderBody(MarkupWriter)}, false to skip to
+     *         {@link #afterRender(MarkupWriter)}.
+     */
+    boolean renderTag(MarkupWriter writer);
+
+    /**
+     * Invoked just before rendering the body of component.
+     * 
+     * @return true to render the body before advancing to {@link #renderCloseTag(MarkupWriter)},
+     *         or false to skip the body and advance directly to
+     *         {@link #renderCloseTag(MarkupWriter)}.
+     */
+    boolean beforeRenderBody(MarkupWriter writer);
+
+    /**
+     * Renders the close tag. Decides whether to render the the tag (and its template and/or body)
+     * again.
+     * 
+     * @return true to return to {@link #renderTag(MarkupWriter)}, or false to advance to
+     *         {@link #afterRender(MarkupWriter)}.
+     */
+    boolean renderCloseTag(MarkupWriter writer);
+
+    /**
+     * Generally used to perform final cleanup of the component after rendering.
+     * 
+     * @return true to re-render the component, returning to {@link #beforeRender(MarkupWriter)},
+     *         or false to indicate that rendering of the component is complete.
+     */
+    boolean afterRender(MarkupWriter writer);
 }

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/RenderCommand.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/RenderCommand.java?rev=434590&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/RenderCommand.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/RenderCommand.java Thu Aug 24 18:30:27 2006
@@ -0,0 +1,13 @@
+package org.apache.tapestry.runtime;
+
+import org.apache.tapestry.MarkupWriter;
+
+/**
+ * A command used during rendering of a page.
+ * 
+ * @author Howard M. Lewis Ship
+ */
+public interface RenderCommand
+{
+    void render(MarkupWriter writer, RenderQueue rendering);
+}

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/RenderQueue.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/RenderQueue.java?rev=434590&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/RenderQueue.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/RenderQueue.java Thu Aug 24 18:30:27 2006
@@ -0,0 +1,12 @@
+package org.apache.tapestry.runtime;
+
+/**
+ * A stateful object that manages the process of rendering a page. Rending a page in Tapestry is
+ * based on a command queue.
+ * 
+ * @author Howard M. Lewis Ship
+ */
+public interface RenderQueue
+{
+    void addFirst(RenderCommand command);
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/ComponentClassResolver.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/ComponentClassResolver.java?rev=434590&r1=434589&r2=434590&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/ComponentClassResolver.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/ComponentClassResolver.java Thu Aug 24 18:30:27 2006
@@ -40,4 +40,12 @@
      * @return fully qualified name
      */
     String resolveComponentName(String inputComponentName);
+
+    /**
+     * Sets the root package for the application. Pages are expected to be in a sub-package named
+     * "pages" (i.e., root.pages). Components will be in a sub-package named "components".
+     * 
+     * @param packageName
+     */
+    void setApplicationPackage(String packageName);
 }

Added: tapestry/tapestry5/tapestry-core/trunk/src/render-states.ygf
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/render-states.ygf?rev=434590&view=auto
==============================================================================
Binary file - no diff available.

Propchange: tapestry/tapestry5/tapestry-core/trunk/src/render-states.ygf
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/PageElementFactoryImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/PageElementFactoryImplTest.java?rev=434590&r1=434589&r2=434590&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/PageElementFactoryImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/PageElementFactoryImplTest.java Thu Aug 24 18:30:27 2006
@@ -25,6 +25,7 @@
 import org.apache.tapestry.internal.services.PageElementFactoryImpl;
 import org.apache.tapestry.internal.structure.PageElement;
 import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.runtime.RenderQueue;
 import org.testng.annotations.Test;
 
 /**
@@ -38,6 +39,7 @@
         ComponentInstantiatorSource source = newComponentInstantiatorSource();
         MarkupWriter writer = new MarkupWriterImpl();
         Location l = newLocation();
+        RenderQueue queue = newRenderQueue();
 
         replay();
 
@@ -46,7 +48,7 @@
 
         PageElement element = factory.newStartElement(token);
 
-        element.render(writer);
+        element.render(writer, queue);
 
         verify();
 
@@ -59,6 +61,7 @@
         ComponentInstantiatorSource source = newComponentInstantiatorSource();
         MarkupWriter writer = new MarkupWriterImpl();
         Location l = newLocation();
+        RenderQueue queue = newRenderQueue();
 
         replay();
 
@@ -69,7 +72,7 @@
 
         writer.element("root");
 
-        element.render(writer);
+        element.render(writer, queue);
 
         verify();
 
@@ -82,6 +85,7 @@
         ComponentInstantiatorSource source = newComponentInstantiatorSource();
         MarkupWriter writer = new MarkupWriterImpl();
         Location l = newLocation();
+        RenderQueue queue = newRenderQueue();
 
         replay();
 
@@ -94,7 +98,7 @@
         writer.write("before");
         writer.element("nested");
 
-        element.render(writer);
+        element.render(writer, queue);
 
         writer.write("after");
 
@@ -128,6 +132,7 @@
         ComponentInstantiatorSource source = newComponentInstantiatorSource();
         MarkupWriter writer = new MarkupWriterImpl();
         Location l = newLocation();
+        RenderQueue queue = newRenderQueue();
 
         replay();
 
@@ -137,7 +142,7 @@
         PageElement element = factory.newTextElement(token);
 
         writer.element("root");
-        element.render(writer);
+        element.render(writer, queue);
 
         verify();
 

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/PagePoolImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/PagePoolImplTest.java?rev=434590&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/PagePoolImplTest.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/PagePoolImplTest.java Thu Aug 24 18:30:27 2006
@@ -0,0 +1,91 @@
+package org.apache.tapestry.internal.services;
+
+import java.util.Locale;
+
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.testng.annotations.Test;
+
+/**
+ * @author Howard M. Lewis Ship
+ */
+public class PagePoolImplTest extends InternalBaseTestCase
+{
+    private static final String PAGE_NAME = "com.foo.pages.MyPage";
+
+    // This will change once we start supporting application localization.
+
+    private final Locale _locale = Locale.getDefault();
+
+    @Test
+    public void checkout_when_page_list_is_null()
+    {
+        PageLoader loader = newPageLoader();
+        Page page = newPage();
+
+        trainLoadPage(loader, PAGE_NAME, _locale, page);
+
+        replay();
+
+        PagePool pool = new PagePoolImpl(loader);
+
+        assertSame(page, pool.checkout(PAGE_NAME));
+
+        verify();
+    }
+
+    @Test
+    public void checkout_when_page_list_is_empty()
+    {
+        PageLoader loader = newPageLoader();
+        Page page1 = newPage();
+        Page page2 = newPage();
+
+        page1.detached();
+        trainGetName(page1, PAGE_NAME);
+
+        trainLoadPage(loader, PAGE_NAME, _locale, page2);
+
+        replay();
+
+        PagePool pool = new PagePoolImpl(loader);
+
+        pool.release(page1);
+
+        assertSame(page1, pool.checkout(PAGE_NAME));
+
+        // Now the list is empty, but not null.
+
+        assertSame(page2, pool.checkout(PAGE_NAME));
+
+        verify();
+    }
+
+    @Test
+    public void release_last_in_first_out()
+    {
+        PageLoader loader = newPageLoader();
+        Page page1 = newPage();
+        Page page2 = newPage();
+
+        page1.detached();
+
+        trainGetName(page1, PAGE_NAME);
+
+        page2.detached();
+
+        trainGetName(page2, PAGE_NAME);
+
+        replay();
+
+        PagePool pool = new PagePoolImpl(loader);
+
+        pool.release(page1);
+        pool.release(page2);
+
+        assertSame(page2, pool.checkout(PAGE_NAME));
+        assertSame(page1, pool.checkout(PAGE_NAME));
+
+        verify();
+    }
+}

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/RequestPageCacheImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/RequestPageCacheImplTest.java?rev=434590&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/RequestPageCacheImplTest.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/RequestPageCacheImplTest.java Thu Aug 24 18:30:27 2006
@@ -0,0 +1,39 @@
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.testng.annotations.Test;
+
+public class RequestPageCacheImplTest extends InternalBaseTestCase
+{
+    private static final String PAGE_NAME = "com.foo.pages.MyPage";
+
+    @Test
+    public void get_is_cached()
+    {
+        PagePool pool = newPagePool();
+        Page page = newPage();
+
+        pool.checkout(PAGE_NAME);
+        setReturnValue(page);
+
+        page.attached();
+
+        pool.release(page);
+
+        replay();
+
+        RequestPageCacheImpl cache = new RequestPageCacheImpl(pool);
+
+        assertSame(cache.get(PAGE_NAME), page);
+
+        // Again, same object, but no PagePool this time.
+        assertSame(cache.get(PAGE_NAME), page);
+
+        // Now, trigger the release()
+
+        cache.threadDidCleanup();
+
+        verify();
+    }
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/structure/PageImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/structure/PageImplTest.java?rev=434590&r1=434589&r2=434590&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/structure/PageImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/structure/PageImplTest.java Thu Aug 24 18:30:27 2006
@@ -51,7 +51,7 @@
         page.addComponentLifecycle(cl1);
         page.addComponentLifecycle(cl2);
 
-        page.detach();
+        page.detached();
 
         verify();
     }