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 2006/06/05 18:47:02 UTC
svn commit: r411855 - in /tapestry/tapestry5/tapestry-core/trunk/src:
main/java/org/apache/tapestry/ main/java/org/apache/tapestry/internal/event/
main/java/org/apache/tapestry/internal/pageload/
main/java/org/apache/tapestry/internal/parser/ main/java...
Author: hlship
Date: Mon Jun 5 09:47:00 2006
New Revision: 411855
URL: http://svn.apache.org/viewvc?rev=411855&view=rev
Log:
Start work on the page loader
Added:
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/Renderable.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/event/InvalidationEventHubImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/pageload/
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/pageload/ComponentTemplateSource.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/pageload/ComponentTemplateSourceImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/pageload/PageLoader.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/pageload/PageLoaderImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/TokenType.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/MarkupPageElement.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/pageload/
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/pageload/ComponentTemplateSourceImplTest.java
tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/internal/pageload/
tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/internal/pageload/Fred.html
Modified:
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/AttributeToken.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/CDATAToken.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/CommentToken.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/EndElementToken.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/StartComponentToken.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/StartElementToken.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/TemplateToken.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/TextToken.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/transform/ComponentInstantiatorSource.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSourceImpl.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/test/BaseTestCase.java
tapestry/tapestry5/tapestry-core/trunk/src/test/conf/testng.xml
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/parser/TemplateParserImplTest.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSourceImplTest.java
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/Renderable.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/Renderable.java?rev=411855&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/Renderable.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/Renderable.java Mon Jun 5 09:47:00 2006
@@ -0,0 +1,12 @@
+package org.apache.tapestry;
+
+/**
+ * Base interface for objects that can render markup output using a
+ * {@link org.apache.tapestry.MarkupWriter}.
+ *
+ * @author Howard M. Lewis Ship
+ */
+public interface Renderable
+{
+ void render(MarkupWriter writer);
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/event/InvalidationEventHubImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/event/InvalidationEventHubImpl.java?rev=411855&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/event/InvalidationEventHubImpl.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/event/InvalidationEventHubImpl.java Mon Jun 5 09:47:00 2006
@@ -0,0 +1,41 @@
+package org.apache.tapestry.internal.event;
+
+import static org.apache.tapestry.util.CollectionFactory.newThreadSafeList;
+
+import java.util.List;
+
+import org.apache.tapestry.events.InvalidationEvent;
+import org.apache.tapestry.events.InvalidationListener;
+
+/**
+ * Base implementation class for classes (especially services) that need to manage a list of
+ * {@link org.apache.tapestry.events.InvalidationListener}s.
+ *
+ * @author Howard M. Lewis Ship
+ */
+public class InvalidationEventHubImpl implements InvalidationEventHub
+{
+ private final List<InvalidationListener> _listeners = newThreadSafeList();
+
+ /** Fires an {@link InvalidationEvent} to all {@link InvalidationListener listener}s. */
+ protected final void fireInvalidationEvent()
+ {
+ InvalidationEvent invalidationEvent = new InvalidationEvent(this);
+
+ for (InvalidationListener listener : _listeners)
+ {
+ listener.objectWasInvalidated(invalidationEvent);
+ }
+ }
+
+ public final void addInvalidationListener(InvalidationListener listener)
+ {
+ _listeners.add(listener);
+ }
+
+ public final void removeInvalidationListener(InvalidationListener listener)
+ {
+ _listeners.remove(listener);
+ }
+
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/pageload/ComponentTemplateSource.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/pageload/ComponentTemplateSource.java?rev=411855&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/pageload/ComponentTemplateSource.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/pageload/ComponentTemplateSource.java Mon Jun 5 09:47:00 2006
@@ -0,0 +1,31 @@
+package org.apache.tapestry.internal.pageload;
+
+import java.util.Locale;
+
+import org.apache.tapestry.internal.event.InvalidationEventHub;
+import org.apache.tapestry.internal.parser.ComponentTemplate;
+
+/**
+ * Provides access to cached {@link org.apache.tapestry.internal.parser.ComponentTemplate}s. The
+ * source acts as a invalidation event hub, and will broadcast invalidation events when any loaded
+ * template resource changes. The listener for these invalidation events is the page source, which
+ * stores cached page instances.
+ * <p>
+ * TODO: A more sophisticated, finer grained dependency manager.
+ *
+ * @author Howard M. Lewis Ship
+ */
+public interface ComponentTemplateSource extends InvalidationEventHub
+{
+ /**
+ * Provides access to a template. The template will be parsed as necessary.
+ *
+ * @param componentName
+ * the fully qualified class name of the component
+ * @param locale
+ * the locale to find the template within
+ * @return the cached template instance, if a template exists, or null if the template does not
+ * exist
+ */
+ ComponentTemplate getTemplate(String componentName, Locale locale);
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/pageload/ComponentTemplateSourceImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/pageload/ComponentTemplateSourceImpl.java?rev=411855&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/pageload/ComponentTemplateSourceImpl.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/pageload/ComponentTemplateSourceImpl.java Mon Jun 5 09:47:00 2006
@@ -0,0 +1,128 @@
+package org.apache.tapestry.internal.pageload;
+
+import static org.apache.tapestry.util.CollectionFactory.newMap;
+
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.hivemind.ClassResolver;
+import org.apache.hivemind.Resource;
+import org.apache.hivemind.util.ClasspathResource;
+import org.apache.tapestry.events.UpdateEvent;
+import org.apache.tapestry.events.UpdateListener;
+import org.apache.tapestry.internal.annotations.Synchronized;
+import org.apache.tapestry.internal.event.InvalidationEventHubImpl;
+import org.apache.tapestry.internal.parser.ComponentTemplate;
+import org.apache.tapestry.internal.parser.TemplateParser;
+import org.apache.tapestry.internal.util.URLChangeTracker;
+
+/**
+ * Service implementation that manages a cache of parsed component templates.
+ *
+ * @author Howard M. Lewis Ship
+ */
+@Synchronized
+public final class ComponentTemplateSourceImpl extends InvalidationEventHubImpl implements
+ ComponentTemplateSource, UpdateListener
+{
+ private ClassResolver _classResolver;
+
+ private TemplateParser _parser;
+
+ /**
+ * Caches from a key (combining component name and locale) to a resource. Often, many different
+ * keys will point to the same resource (i.e., "foo:en_US", "foo:en_UK", and "foo:en" may all be
+ * parsed from the same "foo.html" resource). The resource may end up being null, meaning the
+ * template does not exist in any locale.
+ */
+ private final Map<String, Resource> _templateResources = newMap();
+
+ /**
+ * Cache of parsed templates, keyed on resource.
+ */
+ private final Map<Resource, ComponentTemplate> _templates = newMap();
+
+ private final URLChangeTracker _tracker = new URLChangeTracker();
+
+ /**
+ * Resolves the component name to a {@link Resource} and finds the localization of that resource
+ * (the combination of component name and locale is resolved to a resource). The localized
+ * resource is used as the key to a cache of {@link ComponentTemplate}s.
+ */
+ @Synchronized.Read
+ public ComponentTemplate getTemplate(String componentName, Locale locale)
+ {
+ String key = componentName + ":" + locale.toString();
+
+ if (!_templateResources.containsKey(key))
+ locateTemplateResource(componentName, locale, key);
+
+ Resource resource = _templateResources.get(key);
+
+ // If we were unable to locate the template, then there's no point in trying
+ // to parse it.
+
+ if (resource == null)
+ return null;
+
+ // If we haven't yet parsed the template into the cache, do so now.
+
+ if (!_templates.containsKey(resource))
+ parseTemplate(resource);
+
+ return _templates.get(resource);
+ }
+
+ @Synchronized.Write
+ private void parseTemplate(Resource r)
+ {
+ _tracker.add(r.getResourceURL());
+
+ ComponentTemplate template = _parser.parseTemplate(r);
+
+ _templates.put(r, template);
+ }
+
+ @Synchronized.Write
+ private void locateTemplateResource(String componentName, Locale locale, String key)
+ {
+ // TODO: Currently hard-coded to a ".html" extension! Need to locate the
+ // ComoponentModel and determine the correct extension from that.
+
+ String path = componentName.replace('.', '/') + ".html";
+ Resource baseResource = new ClasspathResource(_classResolver, path);
+ Resource localized = baseResource.getLocalization(locale);
+
+ _templateResources.put(key, localized);
+
+ }
+
+ /**
+ * Checks to see if any parsed resource has changed. If so, then all internal caches are
+ * cleared, and an invalidation event is fired. This is brute force ... a more targetted
+ * dependency management strategy may come later.
+ */
+ @Synchronized.Write
+ public void checkForUpdates(UpdateEvent event)
+ {
+ if (_tracker.containsChanges())
+ {
+ _tracker.clear();
+ _templateResources.clear();
+ _templates.clear();
+ fireInvalidationEvent();
+ }
+ }
+
+ /** For injection. */
+ public void setClassResolver(ClassResolver classResolver)
+ {
+ _classResolver = classResolver;
+ }
+
+ /** For injection. */
+ public void setParser(TemplateParser parser)
+ {
+ _parser = parser;
+ }
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/pageload/PageLoader.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/pageload/PageLoader.java?rev=411855&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/pageload/PageLoader.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/pageload/PageLoader.java Mon Jun 5 09:47:00 2006
@@ -0,0 +1,28 @@
+package org.apache.tapestry.internal.pageload;
+
+import java.util.Locale;
+
+import org.apache.tapestry.internal.structure.Page;
+
+/**
+ * Instantiates a fully loaded, configured instance of a Tapestry page. This is a recursive process,
+ * since part of loading a page is to load the page elements for the page. Further, in some cases,
+ * the full component tree is not identified until after each component's template is loaded. Loaded
+ * pages will be used for many requests (on behalf of many different users) and will be pooled
+ * between requests.
+ *
+ * @author Howard M. Lewis Ship
+ */
+public interface PageLoader
+{
+ /**
+ * Loads the page in the given locale.
+ *
+ * @param pageName
+ * fully qualified class name of the root component of the page
+ * @param locale
+ * the locale to load the page and its components in
+ * @see Page#getLocale()
+ */
+ Page loadPage(String pageName, Locale locale);
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/pageload/PageLoaderImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/pageload/PageLoaderImpl.java?rev=411855&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/pageload/PageLoaderImpl.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/pageload/PageLoaderImpl.java Mon Jun 5 09:47:00 2006
@@ -0,0 +1,106 @@
+package org.apache.tapestry.internal.pageload;
+
+import static org.apache.tapestry.util.CollectionFactory.newList;
+
+import java.util.List;
+import java.util.Locale;
+
+import org.apache.tapestry.internal.structure.ComponentPageElement;
+import org.apache.tapestry.internal.structure.ComponentPageElementImpl;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.internal.structure.PageElement;
+import org.apache.tapestry.internal.structure.PageImpl;
+import org.apache.tapestry.internal.transform.ComponentInstantiatorSource;
+import org.apache.tapestry.internal.transform.Instantiator;
+import org.apache.tapestry.runtime.ComponentLifecycle;
+import org.apache.tapestry.util.CollectionFactory;
+
+/**
+ * This implementation is not threadsafe.
+ *
+ * @author Howard M. Lewis Ship
+ */
+public class PageLoaderImpl implements PageLoader
+{
+ private ComponentInstantiatorSource _componentInstantiatorSource;
+
+ private Page _page;
+
+ private Locale _locale;
+
+ /**
+ * Stack of elements within the current template, used to determine on which object to invoke
+ * {@link ComponentPageElement#addToBody(PageElement)}. Each new element (component or
+ * otherwise) will push a value onto this stack, each end element will pop a value off the
+ * stack.
+ */
+ private final List<ComponentPageElement> _elementStack = newList();
+
+ private final List<ComponentPageElement> _componentQueue = newList();
+
+ public Page loadPage(String pageName, Locale locale)
+ {
+ try
+ {
+ _locale = locale;
+
+ _page = new PageImpl(pageName, _locale);
+
+ loadRootComponent(pageName);
+
+ workComponentQueue();
+
+ return _page;
+ }
+ finally
+ {
+ _page = null;
+ _locale = null;
+ _elementStack.clear();
+ _componentQueue.clear();
+ }
+ }
+
+ private void loadRootComponent(String componentName)
+ {
+ Instantiator instantiator = _componentInstantiatorSource.findInstantiator(componentName);
+
+ ComponentPageElement rootComponent = new ComponentPageElementImpl(_page, instantiator);
+
+ _page.setRootElement(rootComponent);
+
+ push(_componentQueue, rootComponent);
+ }
+
+ /** Works the component queue, until exausted. */
+ private void workComponentQueue()
+ {
+
+ }
+
+ /** For injection. */
+ public void setComponentInstantiatorSource(ComponentInstantiatorSource source)
+ {
+ _componentInstantiatorSource = source;
+ }
+
+ static <T> T peek(List<T> stack)
+ {
+ int size = stack.size();
+
+ return stack.get(size - 1);
+ }
+
+ static <T> void pop(List<T> stack)
+ {
+ int size = stack.size();
+
+ stack.remove(size - 1);
+ }
+
+ static <T> void push(List<T> stack, T element)
+ {
+ stack.add(element);
+ }
+
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/AttributeToken.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/AttributeToken.java?rev=411855&r1=411854&r2=411855&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/AttributeToken.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/AttributeToken.java Mon Jun 5 09:47:00 2006
@@ -29,7 +29,7 @@
public AttributeToken(String name, String value, Location location)
{
- super(location);
+ super(TokenType.ATTRIBUTE, location);
_name = name;
_value = value;
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/CDATAToken.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/CDATAToken.java?rev=411855&r1=411854&r2=411855&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/CDATAToken.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/CDATAToken.java Mon Jun 5 09:47:00 2006
@@ -28,7 +28,7 @@
public CDATAToken(String text, Location location)
{
- super(location);
+ super(TokenType.CDATA, location);
_text = text;
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/CommentToken.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/CommentToken.java?rev=411855&r1=411854&r2=411855&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/CommentToken.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/CommentToken.java Mon Jun 5 09:47:00 2006
@@ -27,7 +27,7 @@
public CommentToken(String comment, Location location)
{
- super(location);
+ super(TokenType.COMMENT, location);
_comment = comment;
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/EndElementToken.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/EndElementToken.java?rev=411855&r1=411854&r2=411855&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/EndElementToken.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/EndElementToken.java Mon Jun 5 09:47:00 2006
@@ -25,6 +25,6 @@
{
public EndElementToken(Location location)
{
- super(location);
+ super(TokenType.END_ELEMENT, location);
}
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/StartComponentToken.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/StartComponentToken.java?rev=411855&r1=411854&r2=411855&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/StartComponentToken.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/StartComponentToken.java Mon Jun 5 09:47:00 2006
@@ -43,7 +43,7 @@
@SuppressNullCheck
public StartComponentToken(String id, String type, Location location)
{
- super(location);
+ super(TokenType.START_COMPONENT, location);
_id = id;
_type = type;
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/StartElementToken.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/StartElementToken.java?rev=411855&r1=411854&r2=411855&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/StartElementToken.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/StartElementToken.java Mon Jun 5 09:47:00 2006
@@ -33,7 +33,7 @@
public StartElementToken(String name, Location location)
{
- super(location);
+ super(TokenType.START_ELEMENT, location);
_name = name;
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/TemplateToken.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/TemplateToken.java?rev=411855&r1=411854&r2=411855&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/TemplateToken.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/TemplateToken.java Mon Jun 5 09:47:00 2006
@@ -25,11 +25,19 @@
*/
public abstract class TemplateToken implements Locatable
{
+ private final TokenType _tokenType;
+
private final Location _location;
- public TemplateToken(Location location)
+ public TemplateToken(TokenType tokenType, Location location)
{
+ _tokenType = tokenType;
_location = location;
+ }
+
+ public TokenType getTokenType()
+ {
+ return _tokenType;
}
public Location getLocation()
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/TextToken.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/TextToken.java?rev=411855&r1=411854&r2=411855&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/TextToken.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/TextToken.java Mon Jun 5 09:47:00 2006
@@ -22,7 +22,7 @@
public TextToken(String text, Location location)
{
- super(location);
+ super(TokenType.TEXT, location);
_text = text;
}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/TokenType.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/TokenType.java?rev=411855&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/TokenType.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/TokenType.java Mon Jun 5 09:47:00 2006
@@ -0,0 +1,12 @@
+package org.apache.tapestry.internal.parser;
+
+/**
+ * Defines the different types of {@link org.apache.tapestry.internal.parser.TemplateToken}s. Each
+ * value maps to a particular subclass of TemplateToken.
+ *
+ * @author Howard M. Lewis Ship
+ */
+public enum TokenType {
+
+ ATTRIBUTE, CDATA, COMMENT, END_ELEMENT, START_COMPONENT, START_ELEMENT, TEXT
+}
Added: 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=411855&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElement.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElement.java Mon Jun 5 09:47:00 2006
@@ -0,0 +1,33 @@
+package org.apache.tapestry.internal.structure;
+
+import org.apache.tapestry.internal.InternalComponentResources;
+
+/**
+ * Extended version of {@link org.apache.tapestry.internal.structure.PageElement} for elements that
+ * are, in fact, components (rather than just static markup).
+ *
+ * @author Howard M. Lewis Ship
+ */
+public interface ComponentPageElement extends PageElement, InternalComponentResources
+{
+ /**
+ * Containing component (or null for the root component of a page).
+ */
+ ComponentPageElement getContainer();
+
+ /**
+ * Used during the construction of a page. Adds a page element as part of the template for this
+ * page element. A page element will eventually render by sequentially rendering these elements.
+ * A page elements template is really just the outermost portions of the component's template
+ * ... where a template contains elements that are reall components, those components will
+ * receive portions of the template as their body.
+ */
+
+ void addToTemplate(PageElement element);
+
+ /**
+ *
+ */
+ void addToBody(PageElement element);
+
+}
Added: 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=411855&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java Mon Jun 5 09:47:00 2006
@@ -0,0 +1,71 @@
+package org.apache.tapestry.internal.structure;
+
+import java.util.List;
+
+import org.apache.tapestry.internal.transform.Instantiator;
+import org.apache.tapestry.runtime.ComponentLifecycle;
+import org.apache.tapestry.util.CollectionFactory;
+
+/**
+ * Implements {@link org.apache.tapestry.internal.structure.PageElement} and
+ * {@link org.apache.tapestry.internal.InternalComponentResources}, and represents a component
+ * within an overall page. Much of a component page element's behavior is delegated to user code,
+ * via a {@link org.apache.tapestry.runtime.ComponentLifecycle} instance.
+ *
+ * @author Howard M. Lewis Ship
+ */
+public class ComponentPageElementImpl implements ComponentPageElement
+{
+ private final Page _page;
+
+ private List<PageElement> _template;
+
+ private List<PageElement> _body;
+
+ private final ComponentPageElement _container;
+
+ private final ComponentLifecycle _component;
+
+ /** Constructor for the root component of a page. */
+ public ComponentPageElementImpl(Page page, Instantiator instantiator)
+ {
+ _page = page;
+ _container = null;
+ _component = instantiator.newInstance(this);
+ }
+
+ /**
+ * Constructor for other components embedded within the root component or at deeper levels of
+ * the hierarchy.
+ */
+
+ public ComponentPageElementImpl(Page page, ComponentPageElement container,
+ Instantiator instantiator)
+ {
+ _page = page;
+ _container = container;
+ _component = instantiator.newInstance(this);
+ }
+
+ public ComponentPageElement getContainer()
+ {
+ return _container;
+ }
+
+ public void addToBody(PageElement element)
+ {
+ if (_body == null)
+ _body = CollectionFactory.newList();
+
+ _body.add(element);
+ }
+
+ public void addToTemplate(PageElement element)
+ {
+ if (_template == null)
+ _template = CollectionFactory.newList();
+
+ _template.add(element);
+ }
+
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/MarkupPageElement.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/MarkupPageElement.java?rev=411855&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/MarkupPageElement.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/MarkupPageElement.java Mon Jun 5 09:47:00 2006
@@ -0,0 +1,19 @@
+package org.apache.tapestry.internal.structure;
+
+import org.apache.tapestry.internal.parser.TemplateToken;
+
+/**
+ * Renders static markup based on a {@link org.apache.tapestry.internal.parser.TemplateToken}.
+ *
+ * @author Howard M. Lewis Ship
+ */
+public class MarkupPageElement implements PageElement
+{
+ private final TemplateToken _token;
+
+ public MarkupPageElement(TemplateToken token)
+ {
+ _token = token;
+ }
+
+}
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=411855&r1=411854&r2=411855&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 Mon Jun 5 09:47:00 2006
@@ -16,8 +16,6 @@
import java.util.Locale;
-import org.apache.tapestry.runtime.ComponentLifecycle;
-
/**
* Represents a unique page within the application.
* <p>
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=411855&r1=411854&r2=411855&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 Mon Jun 5 09:47:00 2006
@@ -23,7 +23,4 @@
*/
public interface PageElement
{
- Page getPage();
-
- PageElement getContainer();
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSource.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSource.java?rev=411855&r1=411854&r2=411855&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSource.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSource.java Mon Jun 5 09:47:00 2006
@@ -34,12 +34,15 @@
/**
* Given the name of a component class, provides an instantiator for that component.
+ * Instantiators are cached, so repeated calls to this method with the same class name will
+ * return the same instance; however, callers should also be aware that the instantiators may
+ * lose validity after an invalidation (caused by changes to external Java class files).
*
* @param classname
* FQCN to find (and perhaps transform and load)
* @return an object which can instantiate an instance of the component
*/
- Instantiator createInstantiator(String classname);
+ Instantiator findInstantiator(String classname);
/**
* Adds a controlled package. Only classes within controlled packages are subject to
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSourceImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSourceImpl.java?rev=411855&r1=411854&r2=411855&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSourceImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSourceImpl.java Mon Jun 5 09:47:00 2006
@@ -16,10 +16,8 @@
import static org.apache.tapestry.util.CollectionFactory.newMap;
import static org.apache.tapestry.util.CollectionFactory.newSet;
-import static org.apache.tapestry.util.CollectionFactory.newThreadSafeList;
import java.net.URL;
-import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -34,10 +32,9 @@
import org.apache.commons.logging.Log;
import org.apache.hivemind.ClassResolver;
-import org.apache.tapestry.events.InvalidationEvent;
-import org.apache.tapestry.events.InvalidationListener;
import org.apache.tapestry.events.UpdateEvent;
import org.apache.tapestry.events.UpdateListener;
+import org.apache.tapestry.internal.event.InvalidationEventHubImpl;
import org.apache.tapestry.internal.util.URLChangeTracker;
import org.apache.tapestry.util.Defense;
@@ -47,8 +44,8 @@
*
* @author Howard M. Lewis Ship
*/
-public final class ComponentInstantiatorSourceImpl implements Translator,
- ComponentInstantiatorSource, UpdateListener
+public final class ComponentInstantiatorSourceImpl extends InvalidationEventHubImpl implements
+ Translator, ComponentInstantiatorSource, UpdateListener
{
private final Set<String> _controlledPackageNames = newSet();
@@ -67,8 +64,6 @@
/** Map from class name to Instantiator. */
private final Map<String, Instantiator> _instantiatorMap = newMap();
- private final List<InvalidationListener> _listeners = newThreadSafeList();
-
/** @return the class loader used when loading enhanced/modified classes */
public ClassLoader getClassLoader()
{
@@ -120,12 +115,7 @@
initializeService();
- InvalidationEvent invalidationEvent = new InvalidationEvent(this);
-
- for (InvalidationListener listener : _listeners)
- {
- listener.objectWasInvalidated(invalidationEvent);
- }
+ fireInvalidationEvent();
}
public void initializeService()
@@ -201,7 +191,7 @@
{
}
- public synchronized Instantiator createInstantiator(String classname)
+ public synchronized Instantiator findInstantiator(String classname)
{
Instantiator result = _instantiatorMap.get(classname);
@@ -279,16 +269,6 @@
public void setLog(Log log)
{
_log = log;
- }
-
- public void addInvalidationListener(InvalidationListener listener)
- {
- _listeners.add(listener);
- }
-
- public void removeInvalidationListener(InvalidationListener listener)
- {
- _listeners.remove(listener);
}
}
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=411855&r1=411854&r2=411855&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 Mon Jun 5 09:47:00 2006
@@ -14,12 +14,11 @@
package org.apache.tapestry.runtime;
-
/**
- * Interface that allows a component to define behavior as the page is loaded. This interface is
- * part of the public API for Tapestry, but is <em>not</em> expected to be directly implemented by
- * component classes; it should only be implemented as part of the component class transformation
- * process.
+ * 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,
+ * but is <em>not</em> expected to be directly implemented by component classes; it should only be
+ * implemented as part of the component class transformation process.
*
* @author Howard M. Lewis Ship
*/
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/BaseTestCase.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/BaseTestCase.java?rev=411855&r1=411854&r2=411855&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/BaseTestCase.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/BaseTestCase.java Mon Jun 5 09:47:00 2006
@@ -14,12 +14,24 @@
package org.apache.tapestry.test;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
import java.lang.annotation.Annotation;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
import java.util.List;
+import java.util.UUID;
import org.apache.commons.logging.Log;
+import org.apache.hivemind.Resource;
+import org.apache.hivemind.util.ClasspathResource;
import org.apache.tapestry.internal.InternalComponentResources;
import org.apache.tapestry.internal.annotations.SuppressNullCheck;
+import org.apache.tapestry.internal.parser.ComponentTemplate;
import org.apache.tapestry.model.MutableComponentModel;
import org.apache.tapestry.transform.ClassTransformation;
@@ -87,6 +99,55 @@
{
transformation.findUnclaimedFields();
setReturnValue(fieldNames);
+ }
+
+
+
+ /** Writes a change to a file. */
+ protected final void touch(File f) throws FileNotFoundException, IOException
+ {
+ OutputStream o = new FileOutputStream(f);
+ o.write(0);
+ o.close();
+ }
+
+ /**
+ * Creates a new class loader, whose parent is the thread's context class loader, but adds a
+ * single classpath root from the filesystem.
+ *
+ * @see #createClasspathRoot()
+ */
+ protected final URLClassLoader newLoaderWithClasspathRoot(File rootDir) throws MalformedURLException
+ {
+ String urlPath = rootDir.toURL().toString();
+ // URLs for folders must end with a slash to make URLClassLoader happy.
+ URL url = new URL(urlPath + "/");
+
+ return new URLClassLoader(new URL[]
+ { url }, Thread.currentThread().getContextClassLoader());
+ }
+
+ /**
+ * Creates a new temporary directory which can act as a classpath root.
+ *
+ * @see #newLoaderWithClasspathRoot(File)
+ */
+ protected final File createClasspathRoot()
+ {
+ String temp = System.getProperty("java.io.tmpdir");
+ String rootDirPath = temp + "/" + UUID.randomUUID().toString();
+
+ return new File(rootDirPath);
+ }
+
+ protected final Resource newResource()
+ {
+ return newMock(Resource.class);
+ }
+
+ protected final ComponentTemplate newComponentTemplate()
+ {
+ return newMock(ComponentTemplate.class);
}
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/conf/testng.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/conf/testng.xml?rev=411855&r1=411854&r2=411855&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/conf/testng.xml (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/conf/testng.xml Mon Jun 5 09:47:00 2006
@@ -24,6 +24,7 @@
<package name="org.apache.tapestry.internal.aspects"/>
<package name="org.apache.tapestry.internal.util"/>
<package name="org.apache.tapestry.internal.parser"/>
+ <package name="org.apache.tapestry.internal.pageload"/>
<package name="org.apache.tapestry.util"/>
</packages>
</test>
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/pageload/ComponentTemplateSourceImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/pageload/ComponentTemplateSourceImplTest.java?rev=411855&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/pageload/ComponentTemplateSourceImplTest.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/pageload/ComponentTemplateSourceImplTest.java Mon Jun 5 09:47:00 2006
@@ -0,0 +1,197 @@
+package org.apache.tapestry.internal.pageload;
+
+import static org.testng.Assert.assertSame;
+
+import java.io.File;
+import java.net.URLClassLoader;
+import java.util.Locale;
+
+import org.apache.hivemind.ClassResolver;
+import org.apache.hivemind.Resource;
+import org.apache.hivemind.impl.DefaultClassResolver;
+import org.apache.hivemind.util.ClasspathResource;
+import org.apache.tapestry.events.InvalidationEvent;
+import org.apache.tapestry.events.InvalidationListener;
+import org.apache.tapestry.events.UpdateEvent;
+import org.apache.tapestry.internal.parser.ComponentTemplate;
+import org.apache.tapestry.internal.parser.TemplateParser;
+import org.apache.tapestry.test.BaseTestCase;
+import org.easymock.EasyMock;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * @author Howard M. Lewis Ship
+ */
+public class ComponentTemplateSourceImplTest extends BaseTestCase
+{
+ private static final String PACKAGE = "org.apache.tapestry.internal.pageload";
+
+ static public final String PATH = "org/apache/tapestry/internal/pageload";
+
+ public ClassResolver _resolver = new DefaultClassResolver();
+
+ @Test
+ public void caching()
+ {
+ Resource r = newResource("Fred.html");
+
+ TemplateParser parser = newTemplateParser();
+ ComponentTemplate template = newComponentTemplate();
+
+ trainParseTemplate(parser, r, template);
+
+ replay();
+
+ ComponentTemplateSourceImpl source = new ComponentTemplateSourceImpl();
+ source.setParser(parser);
+ source.setClassResolver(_resolver);
+
+ String name = PACKAGE + ".Fred";
+ assertSame(source.getTemplate(name, Locale.ENGLISH), template);
+
+ // A second pass will test the caching (the
+ // parser is not invoked).
+
+ assertSame(source.getTemplate(name, Locale.ENGLISH), template);
+
+ verify();
+ }
+
+ private void trainParseTemplate(TemplateParser parser, Resource resource,
+ ComponentTemplate template)
+ {
+ parser.parseTemplate(resource);
+ setReturnValue(template);
+ }
+
+ /** Tests resource invalidation. */
+ @Test
+ public void invalidation() throws Exception
+ {
+ File rootDir = createClasspathRoot();
+ URLClassLoader loader = newLoaderWithClasspathRoot(rootDir);
+
+ File packageDir = new File(rootDir, "baz");
+ packageDir.mkdirs();
+
+ File f = new File(packageDir, "Biff.html");
+
+ f.createNewFile();
+
+ // A special resolver that knows about our special class path.
+
+ ClassResolver resolver = new DefaultClassResolver(loader);
+
+ Resource localized = new ClasspathResource(resolver, "baz/Biff.html");
+
+ TemplateParser parser = newTemplateParser();
+ ComponentTemplate template = newComponentTemplate();
+ InvalidationListener listener = newMock(InvalidationListener.class);
+
+ trainParseTemplate(parser, localized, template);
+
+ replay();
+
+ ComponentTemplateSourceImpl source = new ComponentTemplateSourceImpl();
+ source.setParser(parser);
+ source.setClassResolver(resolver);
+ source.addInvalidationListener(listener);
+
+ String name = "baz.Biff";
+
+ assertSame(source.getTemplate(name, Locale.ENGLISH), template);
+
+ // Check for updates (which won't be found).
+ source.checkForUpdates(new UpdateEvent(this));
+
+ // A second pass will test the caching (the
+ // parser is not invoked).
+
+ assertSame(source.getTemplate(name, Locale.ENGLISH), template);
+
+ verify();
+
+ // Now, change the file and process an UpdateEvent.
+
+ touch(f);
+
+ listener.objectWasInvalidated(EasyMock.isA(InvalidationEvent.class));
+
+ replay();
+
+ // Check for updates (which will be found).
+ source.checkForUpdates(new UpdateEvent(this));
+
+ verify();
+
+ // Check that the cache really is cleared.
+
+ trainParseTemplate(parser, localized, template);
+
+ replay();
+
+ assertSame(source.getTemplate(name, Locale.ENGLISH), template);
+
+ verify();
+ }
+
+ protected final TemplateParser newTemplateParser()
+ {
+ return newMock(TemplateParser.class);
+ }
+
+ /** Checks that localization to the same resource works (w/ caching). */
+ @Test
+ public void localizationToSame()
+ {
+ Resource r = newResource("Fred.html");
+
+ TemplateParser parser = newTemplateParser();
+ ComponentTemplate template = newComponentTemplate();
+
+ trainParseTemplate(parser, r, template);
+
+ replay();
+
+ ComponentTemplateSourceImpl source = new ComponentTemplateSourceImpl();
+ source.setParser(parser);
+ source.setClassResolver(_resolver);
+
+ String name = PACKAGE + ".Fred";
+ assertSame(source.getTemplate(name, Locale.ENGLISH), template);
+
+ // A second pass finds the same resource, but using a different
+ // path/locale combination.
+
+ assertSame(source.getTemplate(name, Locale.FRENCH), template);
+
+ // A third pass should further demonstrate the caching.
+
+ assertSame(source.getTemplate(name, Locale.FRENCH), template);
+
+ verify();
+ }
+
+ @Test
+ public void notFound()
+ {
+ TemplateParser parser = newTemplateParser();
+
+ replay();
+
+ ComponentTemplateSourceImpl source = new ComponentTemplateSourceImpl();
+ source.setParser(parser);
+ source.setClassResolver(_resolver);
+
+ String name = PACKAGE + ".Barney";
+ Assert.assertNull(source.getTemplate(name, Locale.ENGLISH));
+
+ verify();
+ }
+
+ private Resource newResource(String name)
+ {
+ return new ClasspathResource(_resolver, PATH + "/" + name);
+ }
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/parser/TemplateParserImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/parser/TemplateParserImplTest.java?rev=411855&r1=411854&r2=411855&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/parser/TemplateParserImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/parser/TemplateParserImplTest.java Mon Jun 5 09:47:00 2006
@@ -234,8 +234,7 @@
AttributeToken t1 = get(tokens, 3);
// TODO: Not sure what order the attributes appear in. Order in the XML? Sorted
- // alphbetically?
- // Random 'cause they're hashed?
+ // alphbetically? Random 'cause they're hashed?
assertEquals(t1.getName(), "cherry");
assertEquals(t1.getValue(), "bomb");
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSourceImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSourceImplTest.java?rev=411855&r1=411854&r2=411855&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSourceImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSourceImplTest.java Mon Jun 5 09:47:00 2006
@@ -208,7 +208,7 @@
// Can't wait for the HiveMind code base to start using some generics for this kind of
// thing.
- Instantiator inst = _source.createInstantiator(classname);
+ Instantiator inst = _source.findInstantiator(classname);
ComponentLifecycle target = inst.newInstance(resources);
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/internal/pageload/Fred.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/internal/pageload/Fred.html?rev=411855&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/internal/pageload/Fred.html (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/internal/pageload/Fred.html Mon Jun 5 09:47:00 2006
@@ -0,0 +1 @@
+<html> Used by ComponentTemplateSourceImplTest </html>