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/09/14 05:55:53 UTC

svn commit: r443216 - in /tapestry/tapestry5/tapestry-core/trunk/src: main/java/org/apache/tapestry/internal/parser/ main/java/org/apache/tapestry/internal/services/ main/java/org/apache/tapestry/services/ main/resources/org/apache/tapestry/internal/se...

Author: hlship
Date: Wed Sep 13 20:55:51 2006
New Revision: 443216

URL: http://svn.apache.org/viewvc?view=rev&rev=443216
Log:
Change the template parser to collect component ids as part of the ComponentTemplate.
Allow the id attribute of the <comp> element to be omitted.

Added:
    tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/internal/services/component_ids.html
    tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/internal/services/component_without_id_or_type.html
Modified:
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/ComponentTemplate.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/ComponentTemplateImpl.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/services/ComponentClassResolverImpl.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/PageElementFactory.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/PageLoaderImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/TemplateParserImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/ComponentClassResolver.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/services/ServicesStrings.properties
    tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/templates.apt
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/TemplateParserImplTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/VisibilityBean.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/InjectPage.html
    tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/MerryChristmas.html
    tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/Start.html

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/ComponentTemplate.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/ComponentTemplate.java?view=diff&rev=443216&r1=443215&r2=443216
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/ComponentTemplate.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/ComponentTemplate.java Wed Sep 13 20:55:51 2006
@@ -15,6 +15,7 @@
 package org.apache.tapestry.internal.parser;
 
 import java.util.List;
+import java.util.Set;
 
 import org.apache.tapestry.Resource;
 
@@ -33,4 +34,10 @@
      * this list.
      */
     List<TemplateToken> getTokens();
+
+    /**
+     * Returns a set of strings corresponding to {@link StartComponentToken}s within the template
+     * that have a non-blank id attribute.
+     */
+    Set<String> getComponentIds();
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/ComponentTemplateImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/ComponentTemplateImpl.java?view=diff&rev=443216&r1=443215&r2=443216
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/ComponentTemplateImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/ComponentTemplateImpl.java Wed Sep 13 20:55:51 2006
@@ -15,10 +15,12 @@
 package org.apache.tapestry.internal.parser;
 
 import java.util.List;
+import java.util.Set;
 
 import org.apache.tapestry.Resource;
 
 import static org.apache.tapestry.util.CollectionFactory.newList;
+import static org.apache.tapestry.util.CollectionFactory.newSet;
 
 /**
  * @author Howard M. Lewis Ship
@@ -29,16 +31,22 @@
 
     private final List<TemplateToken> _tokens;
 
+    private final Set<String> _componentIds;
+
     /**
      * @param resource
      *            the resource from which the template was parsed
      * @param tokens
      *            the tokens of the template, a copy of this list will be made
+     * @param componentIds
+     *            TODO
      */
-    public ComponentTemplateImpl(Resource resource, List<TemplateToken> tokens)
+    public ComponentTemplateImpl(Resource resource, List<TemplateToken> tokens,
+            Set<String> componentIds)
     {
         _resource = resource;
         _tokens = newList(tokens);
+        _componentIds = newSet(componentIds);
     }
 
     public Resource getResource()
@@ -49,5 +57,10 @@
     public List<TemplateToken> getTokens()
     {
         return _tokens;
+    }
+
+    public Set<String> getComponentIds()
+    {
+        return _componentIds;
     }
 }

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?view=diff&rev=443216&r1=443215&r2=443216
==============================================================================
--- 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 Wed Sep 13 20:55:51 2006
@@ -45,17 +45,25 @@
     {
         super(TokenType.START_COMPONENT, location);
 
-        // TODO: id or type may be null, nut not both!
+        // TODO: id or type may be null, but not both!
 
         _id = id;
         _type = type;
     }
 
+    /**
+     * Returns a non-blank id if one was provided in the template. If the id attribute was missing
+     * (or the value was blank), returns null.
+     */
     public String getId()
     {
         return _id;
     }
 
+    /**
+     * Returns a non-blank component type if one was provided in the template. If the type attribute
+     * was missing (or the value was blank), returns null.
+     */
     public String getType()
     {
         return _type;
@@ -66,6 +74,5 @@
     {
         return String.format("StartComponent[id=%s, type=%s]", _id, _type);
     }
-    
-    
+
 }

Modified: 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?view=diff&rev=443216&r1=443215&r2=443216
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentClassResolverImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentClassResolverImpl.java Wed Sep 13 20:55:51 2006
@@ -32,9 +32,9 @@
 
     private String _appComponentPackage;
 
-    public String resolvePageName(String inputPageName)
+    public String resolvePageNameToClassName(String pageName)
     {
-        return resolve(_appPagePackage, inputPageName);
+        return resolve(_appPagePackage, pageName);
     }
 
     private String resolve(String packageName, String inputClassName)
@@ -50,9 +50,9 @@
         return packageName + "." + inputClassName;
     }
 
-    public String resolveComponentName(String inputComponentName)
+    public String resolveComponentTypeToClassName(String componentType)
     {
-        return resolve(_appComponentPackage, inputComponentName);
+        return resolve(_appComponentPackage, componentType);
     }
 
     public void setApplicationPackage(String packageName)

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?view=diff&rev=443216&r1=443215&r2=443216
==============================================================================
--- 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 Wed Sep 13 20:55:51 2006
@@ -61,7 +61,7 @@
 
         String minimalPageName = path.substring(1, pos);
 
-        String fullPageName = _resolver.resolvePageName(minimalPageName);
+        String fullPageName = _resolver.resolvePageNameToClassName(minimalPageName);
 
         Page page = _cache.get(fullPageName);
 

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageElementFactory.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageElementFactory.java?view=diff&rev=443216&r1=443215&r2=443216
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageElementFactory.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageElementFactory.java Wed Sep 13 20:55:51 2006
@@ -14,8 +14,8 @@
 
 package org.apache.tapestry.internal.services;
 
+import org.apache.tapestry.Location;
 import org.apache.tapestry.internal.parser.AttributeToken;
-import org.apache.tapestry.internal.parser.StartComponentToken;
 import org.apache.tapestry.internal.parser.StartElementToken;
 import org.apache.tapestry.internal.parser.TextToken;
 import org.apache.tapestry.internal.structure.ComponentPageElement;
@@ -37,10 +37,10 @@
 
     PageElement newEndElement();
 
-    ComponentPageElement newComponentElement(Page page, ComponentPageElement container,
-            StartComponentToken token);
+    ComponentPageElement newComponentElement(Page page, ComponentPageElement container, String id,
+            String componentType, Location location);
 
-    ComponentPageElement newRootComponentElement(Page page, String componentName);
+    ComponentPageElement newRootComponentElement(Page page, String componentType);
 
     PageElement newRenderBodyElement(ComponentPageElement component);
 }

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?view=diff&rev=443216&r1=443215&r2=443216
==============================================================================
--- 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 Wed Sep 13 20:55:51 2006
@@ -14,9 +14,9 @@
 
 package org.apache.tapestry.internal.services;
 
+import org.apache.tapestry.Location;
 import org.apache.tapestry.MarkupWriter;
 import org.apache.tapestry.internal.parser.AttributeToken;
-import org.apache.tapestry.internal.parser.StartComponentToken;
 import org.apache.tapestry.internal.parser.StartElementToken;
 import org.apache.tapestry.internal.parser.TextToken;
 import org.apache.tapestry.internal.structure.AttributePageElement;
@@ -82,18 +82,13 @@
     }
 
     public ComponentPageElement newComponentElement(Page page, ComponentPageElement container,
-            StartComponentToken token)
+            String id, String componentType, Location location)
     {
-        // For the moment, we're assuming each component will have an id and a FQCN for
-        // the type. This will change pretty soon.
-
-        String id = token.getId();
-
         // Determining the component name is really not this easy. We may only specify
         // the id in the template, and rely on the component model to provide us with
         // the type.
 
-        String componentName = _componentClassResolver.resolveComponentName(token.getType());
+        String componentName = _componentClassResolver.resolveComponentTypeToClassName(componentType);
 
         Instantiator instantiator = _componentInstantiatorSource.findInstantiator(componentName);
         ComponentModel model = _componentInstantiatorSource.findComponentModel(componentName);
@@ -103,17 +98,17 @@
         // template.
 
         ComponentPageElementImpl result = new ComponentPageElementImpl(page, container, id,
-                instantiator, model, token.getLocation());
+                instantiator, model, location);
 
         page.addLifecycleListener(result);
 
         return result;
     }
 
-    public ComponentPageElement newRootComponentElement(Page page, String componentName)
+    public ComponentPageElement newRootComponentElement(Page page, String componentType)
     {
-        Instantiator instantiator = _componentInstantiatorSource.findInstantiator(componentName);
-        ComponentModel model = _componentInstantiatorSource.findComponentModel(componentName);
+        Instantiator instantiator = _componentInstantiatorSource.findInstantiator(componentType);
+        ComponentModel model = _componentInstantiatorSource.findComponentModel(componentType);
 
         ComponentPageElementImpl result = new ComponentPageElementImpl(page, instantiator, model);
 

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageLoaderImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageLoaderImpl.java?view=diff&rev=443216&r1=443215&r2=443216
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageLoaderImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageLoaderImpl.java Wed Sep 13 20:55:51 2006
@@ -33,12 +33,15 @@
 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.model.ComponentModel;
 import org.apache.tapestry.services.BindingSource;
+import org.apache.tapestry.util.IdAllocator;
 
 import static org.apache.tapestry.util.CollectionFactory.newList;
 
 /**
- * This implementation is not threadsafe.
+ * This implementation is not threadsafe, and the "prethread" lifecycle should be used for the
+ * PageLoader service.
  * 
  * @author Howard M. Lewis Ship
  */
@@ -126,15 +129,16 @@
 
     private void loadTemplateForComponent(ComponentPageElement loadingComponent)
     {
-        // Have to do something here, like consult the ComponentModelSource and get a
-        // ComponentModel to guide the process. Lots of moving parts.
+        ComponentModel model = loadingComponent.getComponentModel();
 
-        ComponentTemplate template = _templateSource.getTemplate(loadingComponent
-                .getComponentModel().getComponentClassName(), _locale);
+        ComponentTemplate template = _templateSource.getTemplate(
+                model.getComponentClassName(),
+                _locale);
 
         // Perhaps when template is null, we should act as if the template
         // consists of just a render body element? Also, pages should (probably?)
-        // be required to have a template.
+        // be required to have a template. Somewhere in here, we need
+        // to figure out how to search for a base-class template.
 
         if (template == null)
         {
@@ -142,6 +146,12 @@
             return;
         }
 
+        // Pre-allocate ids to avoid later name collisions.
+
+        IdAllocator idAllocator = new IdAllocator();
+        for (String id : template.getComponentIds())
+            idAllocator.allocateId(id);
+
         // Here's the thing. Stuff in this template is part of element's template unless
         // it is inside another component, in which case, it is part of the component's
         // body. template is stuff from the component's own template (if any). body
@@ -219,10 +229,26 @@
                     // how the component elements are nested within the loading component's
                     // template.
 
+                    StartComponentToken startComponent = (StartComponentToken) token;
+
+                    String embeddedType = startComponent.getType();
+
+                    String embeddedId = startComponent.getId();
+
+                    // We know that if embeddedId is null, embeddedType is not.
+
+                    if (embeddedId == null)
+                        embeddedId = generateEmbeddedId(embeddedType, idAllocator);
+
+                    // TODO: Determine the type from from the ComponentModel if not present in the
+                    // template.
+
                     ComponentPageElement newComponent = _pageElementFactory.newComponentElement(
                             _page,
                             loadingComponent,
-                            ((StartComponentToken) token));
+                            embeddedId,
+                            embeddedType,
+                            startComponent.getLocation());
 
                     add(loadingComponent, activeComponent, newComponent);
 
@@ -269,19 +295,30 @@
             }
 
         }
+    }
+
+    private String generateEmbeddedId(String embeddedType, IdAllocator idAllocator)
+    {
+        // TODO: really should trim to last / OR last .
+
+        int x = embeddedType.lastIndexOf("/");
+
+        // The idAllocator is pre-loaded with all the component ids from the template, so even
+        // if the lower-case type matches the id of an existing component, there won't be a name
+        // collision.
 
+        return idAllocator.allocateId(embeddedType.substring(x + 1).toLowerCase());
     }
 
     private void addBindingToComponent(ComponentResources loadingComponent,
             ComponentPageElement component, AttributeToken token)
     {
         String name = token.getName();
-        String description = "parameter " + name;
 
         // Default binding prefix inside templates is literal.
 
         Binding binding = _bindingSource.newBinding(
-                description,
+                "parameter " + name,
                 loadingComponent,
                 InternalConstants.LITERAL_BINDING_PREFIX,
                 token.getValue(),

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java?view=diff&rev=443216&r1=443215&r2=443216
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java Wed Sep 13 20:55:51 2006
@@ -149,4 +149,9 @@
     {
         return MESSAGES.format("non-private-fields", className, IOCUtilities.joinSorted(names));
     }
+
+    static String compRequiresIdOrType()
+    {
+        return MESSAGES.get("comp-requires-id-or-type");
+    }
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/TemplateParserImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/TemplateParserImpl.java?view=diff&rev=443216&r1=443215&r2=443216
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/TemplateParserImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/TemplateParserImpl.java Wed Sep 13 20:55:51 2006
@@ -17,6 +17,7 @@
 import java.net.URL;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import javax.xml.parsers.SAXParser;
 import javax.xml.parsers.SAXParserFactory;
@@ -26,6 +27,7 @@
 import org.apache.tapestry.Resource;
 import org.apache.tapestry.internal.LocationImpl;
 import org.apache.tapestry.internal.TapestryException;
+import org.apache.tapestry.internal.ioc.IOCUtilities;
 import org.apache.tapestry.internal.parser.AttributeToken;
 import org.apache.tapestry.internal.parser.BodyToken;
 import org.apache.tapestry.internal.parser.CDATAToken;
@@ -47,6 +49,7 @@
 import static org.apache.tapestry.internal.ioc.IOCUtilities.isBlank;
 import static org.apache.tapestry.util.CollectionFactory.newList;
 import static org.apache.tapestry.util.CollectionFactory.newMap;
+import static org.apache.tapestry.util.CollectionFactory.newSet;
 
 /**
  * Non-threadsafe implementation.
@@ -72,6 +75,10 @@
 
     private final List<Map<String, String>> _prefixResolutionStack = newList();
 
+    // Non-blank ids from start component (<comp>) elements
+
+    private final Set<String> _componentIds = newSet();
+
     // Used to accumulate text provided by the characters(). Even contiguous characters may be
     // broken up across multiple invocations due to parser internals. We accumulate those together
     // before forming a text token.
@@ -101,6 +108,7 @@
     {
         _tokens.clear();
         _prefixResolutionStack.clear();
+        _componentIds.clear();
         _templateResource = null;
         _locator = null;
         _textBuffer.setLength(0);
@@ -143,7 +151,7 @@
 
             _parser.parse(source, this);
 
-            return new ComponentTemplateImpl(_templateResource, _tokens);
+            return new ComponentTemplateImpl(_templateResource, _tokens, _componentIds);
         }
         catch (Exception ex)
         {
@@ -314,18 +322,27 @@
 
             if (name.equals("id"))
             {
-                id = value;
+                if (IOCUtilities.isNonBlank(value))
+                    id = value;
                 continue;
             }
 
             if (name.equals("type"))
             {
-                type = value;
+
+                if (IOCUtilities.isNonBlank(value))
+                    type = value;
                 continue;
             }
 
             attributeTokens.add(new AttributeToken(name, value, location));
         }
+
+        if (id == null && type == null)
+            throw new TapestryException(ServicesMessages.compRequiresIdOrType(), location, null);
+
+        if (id != null)
+            _componentIds.add(id);
 
         // Add the component
         _tokens.add(new StartComponentToken(id, type, location));

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?view=diff&rev=443216&r1=443215&r2=443216
==============================================================================
--- 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 Wed Sep 13 20:55:51 2006
@@ -25,21 +25,20 @@
      * Converts a partial page name (such as might be encoded into a URL) into a fully qualified
      * class name.
      * 
-     * @param inputPageName
+     * @param pageName
      *            partial name
-     * @return fully qualified name
+     * @return fully qualified class name
      */
-    String resolvePageName(String inputPageName);
+    String resolvePageNameToClassName(String pageName);
 
     /**
-     * Converts a partial component name (such as might be used inside a template or annotation)
-     * into a fully qualified class name.
+     * Converts a component type (a partial component name such as might be used inside a template
+     * or annotation) into a fully qualified class name.
      * 
-     * @param inputPageName
-     *            partial name
-     * @return fully qualified name
+     * @param componentType
+     * @return fully qualified class name
      */
-    String resolveComponentName(String inputComponentName);
+    String resolveComponentTypeToClassName(String componentType);
 
     /**
      * Sets the root package for the application. Pages are expected to be in a sub-package named

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/services/ServicesStrings.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/services/ServicesStrings.properties?view=diff&rev=443216&r1=443215&r2=443216
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/services/ServicesStrings.properties (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/services/ServicesStrings.properties Wed Sep 13 20:55:51 2006
@@ -39,4 +39,5 @@
   Use the value attribute of the @Inject annotation to identify exactly what should be injected into this field.
 non-private-fields=Class %s contains field(s) (%s) that are not private. Tapestry will ignore these fields, even if they \
   have annotations. Runtime behavior, especially in production, may not be what you expect. \
-  You should change these fields to private, and add accessor methods if needed.  
\ No newline at end of file
+  You should change these fields to private, and add accessor methods if needed.  
+comp-requires-id-or-type=The <comp> element requires either an id or a type attribute to be specified.
\ No newline at end of file

Modified: tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/templates.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/templates.apt?view=diff&rev=443216&r1=443215&r2=443216
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/templates.apt (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/templates.apt Wed Sep 13 20:55:51 2006
@@ -67,7 +67,7 @@
   
   Either id or type must be specified.
   
-  If the id attribute is ommitted, Tapestry will assign a unique id for the element.  <<Not yet implemented.>>
+  If the id attribute is ommitted, Tapestry will assign a unique id for the element.
   
   The type attribute is optional; when not specified, Tapestry will expect the class to define
   the type of the component (with a @Component annotation).  <<Not yet implemented.>>

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java?view=diff&rev=443216&r1=443215&r2=443216
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java Wed Sep 13 20:55:51 2006
@@ -17,9 +17,7 @@
 import org.openqa.selenium.server.SeleniumServer;
 import org.testng.Assert;
 import org.testng.annotations.AfterClass;
-import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeClass;
-import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import com.thoughtworks.selenium.DefaultSelenium;
@@ -55,29 +53,20 @@
 
         _server.start();
 
-    }
-
-    @BeforeMethod
-    public void setupSelenium()
-    {
         _selenium = new DefaultSelenium("localhost", SeleniumServer.DEFAULT_PORT, "*firefox",
                 "http://localhost");
 
         _selenium.start();
     }
 
-    @AfterMethod
-    public void shutdownSelenim()
-    {
-        _selenium.stop();
-        _selenium = null;
-    }
-
     @AfterClass
     public void shutdownBackground() throws Exception
     {
         // Thread.sleep(10000);
 
+        _selenium.stop();
+        _selenium = null;
+
         _server.stop();
         _server = null;
 
@@ -86,7 +75,7 @@
     }
 
     @Test
-    public void app1_basic_output_and_parameters() throws Exception
+    public void app1_basic_output() throws Exception
     {
         _selenium.open(BASE_URL);
 
@@ -106,6 +95,11 @@
         // This is text passed from Start.html to Output as a parameter
 
         assertTrue(body.contains("we have basic parameters working"));
+    }
+
+    @Test
+    public void app1_basic_parameters() throws Exception
+    {
 
         // OK ... this could be a separate test, but for efficiency, we'll mix it in here.
         // It takes a while to start up Selenium RC (and a Firefox browser).
@@ -115,18 +109,22 @@
         _selenium.click("link=Loop Page");
         _selenium.waitForPageToLoad(PAGE_LOAD_TIMEOUT);
 
-        body = _selenium.getBodyText();
+        String body = _selenium.getBodyText();
 
         // Selenium is nice enough to remove the elements and excess whitespace.
 
         assertTrue(body.contains("Ho! Ho! Ho!"));
+    }
 
+    @Test
+    public void app1_injection() throws Exception
+    {
         _selenium.open(BASE_URL);
 
         _selenium.click("link=Inject Page");
         _selenium.waitForPageToLoad(PAGE_LOAD_TIMEOUT);
 
-        body = _selenium.getBodyText();
+        String body = _selenium.getBodyText();
 
         // This is the output from the proxy for the WebRequest service, which is what's injected
         // into and output by, the component.

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/TemplateParserImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/TemplateParserImplTest.java?view=diff&rev=443216&r1=443215&r2=443216
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/TemplateParserImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/TemplateParserImplTest.java Wed Sep 13 20:55:51 2006
@@ -14,7 +14,9 @@
 
 package org.apache.tapestry.internal.services;
 
+import java.util.Arrays;
 import java.util.List;
+import java.util.Set;
 
 import org.apache.commons.logging.Log;
 import org.apache.tapestry.Locatable;
@@ -35,6 +37,7 @@
 import org.apache.tapestry.test.BaseTestCase;
 import org.testng.annotations.Test;
 
+import static org.apache.tapestry.util.CollectionFactory.newSet;
 import static org.easymock.EasyMock.contains;
 
 /**
@@ -162,8 +165,9 @@
 
         TextToken t = get(tokens, 1);
 
-        // This is OK because the org.apache.tapestry.dom.Text will convert the characters back into XML entities.
-        
+        // This is OK because the org.apache.tapestry.dom.Text will convert the characters back into
+        // XML entities.
+
         assertEquals(t.getText().trim(), "lt:< gt:> amp:&");
     }
 
@@ -319,5 +323,36 @@
         assertEquals(t3.getText().trim(), "fred's body");
 
         get(tokens, 6);
+    }
+
+    @Test
+    public void component_without_id_or_type() throws Exception
+    {
+        try
+        {
+            tokens("component_without_id_or_type.html");
+            unreachable();
+        }
+        catch (TapestryException ex)
+        {
+            assertEquals(ex.getCause().getMessage(), ServicesMessages.compRequiresIdOrType());
+            assertEquals(ex.getLocation().getLine(), 2);
+        }
+    }
+
+    @Test
+    public void component_ids() throws Exception
+    {
+        Log log = newLog();
+
+        replay();
+
+        ComponentTemplate template = parse(log, "component_ids.html");
+
+        Set<String> ids = template.getComponentIds();
+
+        assertEquals(ids, newSet(Arrays.asList("bomb", "border", "zebra")));
+
+        verify();
     }
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/VisibilityBean.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/VisibilityBean.java?view=diff&rev=443216&r1=443215&r2=443216
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/VisibilityBean.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/VisibilityBean.java Wed Sep 13 20:55:51 2006
@@ -1,3 +1,17 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
 package org.apache.tapestry.internal.services;
 
 import org.apache.tapestry.annotations.Retain;

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/InjectPage.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/InjectPage.html?view=diff&rev=443216&r1=443215&r2=443216
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/InjectPage.html (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/InjectPage.html Wed Sep 13 20:55:51 2006
@@ -1,6 +1,6 @@
-<t:comp id="border" type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
-    <p> Demonstrates the use of the @Inject annotation. </p>
-    <p>WebRequest: <t:comp id="request" type="Output" value="prop:request"/></p>
-    <p>ComponentResources: <t:comp id="rsources" type="Output" value="prop:resources"/></p>
-    <p>BindingSource: <t:comp id="source" type="Output" value="prop:bindingSource"/></p>
+<t:comp type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <p> Demonstrates the use of the @Inject annotation. </p>
+    <p>WebRequest: <t:comp type="Output" value="prop:request"/></p>
+    <p>ComponentResources: <t:comp type="Output" value="prop:resources"/></p>
+    <p>BindingSource: <t:comp type="Output" value="prop:bindingSource"/></p>
 </t:comp>

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/MerryChristmas.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/MerryChristmas.html?view=diff&rev=443216&r1=443215&r2=443216
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/MerryChristmas.html (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/MerryChristmas.html Wed Sep 13 20:55:51 2006
@@ -1,5 +1,5 @@
-<t:comp id="border" type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+<t:comp type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
     <p> The Loop component demonstrates reading and writing of properties with the prop: binding prefix.</p>
-    <p> Merry Christmas: <t:comp id="loop" type="Loop" max="prop:max"> Ho! </t:comp>
+    <p> Merry Christmas: <t:comp type="Loop" max="prop:max"> Ho! </t:comp>
     </p>
 </t:comp>

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/Start.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/Start.html?view=diff&rev=443216&r1=443215&r2=443216
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/Start.html (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/Start.html Wed Sep 13 20:55:51 2006
@@ -1,12 +1,12 @@
-<t:comp id="border" type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+<t:comp type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
     <p> This is the <span style="font-style: bold; color: blue;">First Tapestry 5 Page,
         ever!</span>. </p>
-    <p> Here's some output from the HelloWorld component: <t:comp id="strong" type="Strong">
-            <t:comp id="hello" type="HelloWorld"/>
+    <p> Here's some output from the HelloWorld component: <t:comp type="Strong">
+            <t:comp type="HelloWorld"/>
         </t:comp>
     </p>
     <p>
         Here's some output from the Output component:
-        <t:comp id="output" type="Output" value="Yep, we have basic parameters working."/>
+        <t:comp type="Output" value="Yep, we have basic parameters working."/>
     </p>
 </t:comp>

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/internal/services/component_ids.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/internal/services/component_ids.html?view=auto&rev=443216
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/internal/services/component_ids.html (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/internal/services/component_ids.html Wed Sep 13 20:55:51 2006
@@ -0,0 +1,5 @@
+<t:comp id="border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <t:comp id="zebra" type="Zebra"/>
+    <t:comp type="Nebraska"/>
+    <t:comp id="bomb"/> 
+</t:comp>
\ No newline at end of file

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/internal/services/component_without_id_or_type.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/internal/services/component_without_id_or_type.html?view=auto&rev=443216
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/internal/services/component_without_id_or_type.html (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/internal/services/component_without_id_or_type.html Wed Sep 13 20:55:51 2006
@@ -0,0 +1,5 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <t:comp cherry="bomb" align="right"> 
+        fred's body 
+    </t:comp>
+</html>