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/11/05 18:01:21 UTC

svn commit: r471463 [1/2] - in /tapestry/tapestry5/tapestry-core/trunk/src: main/java/org/apache/tapestry/ main/java/org/apache/tapestry/annotations/ main/java/org/apache/tapestry/corelib/components/ main/java/org/apache/tapestry/dom/ main/java/org/apa...

Author: hlship
Date: Sun Nov  5 09:01:19 2006
New Revision: 471463

URL: http://svn.apache.org/viewvc?view=rev&rev=471463
Log:
Add missing copyrights.
Change TestBase to provide a normal control (order agnostic, but unexpected method calls are a failure).
Start implementation of form support.

Added:
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentAction.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/Field.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/AbstractField.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/ComponentMessages.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/FormSupportImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/TextField.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentSourceImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageRenderSupportImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/ComponentSource.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/PageRenderSupport.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/corelib/components/
    tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/corelib/components/ComponentStrings.properties
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/SimpleForm.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentSourceImplTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/LinkImplTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/SimpleForm.html
Removed:
    tapestry/tapestry5/tapestry-core/trunk/src/test/app1/render-states1_1.png
Modified:
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentResourcesCommon.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/Link.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/AfterRenderBody.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/AfterRenderTemplate.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/BeforeRenderTemplate.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/Form.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/dom/Element.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentEventDispatcher.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/LinkImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/MarkupWriterImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RequestPageCache.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RequestPageCacheImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/Page.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/PageImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/util/AcceptVoidEventHandler.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/util/Base64InputStream.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/util/Base64ObjectInputStream.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/util/Base64ObjectOutputStream.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/util/Base64OutputStream.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/FormSupport.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/TestBase.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/infrastructure.apt
    tapestry/tapestry5/tapestry-core/trunk/src/site/resources/tap5devwiki.html
    tapestry/tapestry5/tapestry-core/trunk/src/site/resources/tap5devwiki.xml
    tapestry/tapestry5/tapestry-core/trunk/src/test/app1/index.html
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/dom/DOMTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/TypeCoercerImplTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentClassResolverImplTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentLifecycleMethodWorkerTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/MarkupWriterImplTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/MixinWorkerTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/structure/ComponentPageElementImplTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/util/Base64Tests.java

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentAction.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentAction.java?view=auto&rev=471463
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentAction.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentAction.java Sun Nov  5 09:01:19 2006
@@ -0,0 +1,35 @@
+// 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;
+
+import java.io.Serializable;
+
+/**
+ * An action that is associated with a component. This is used in several areas of Tapestry and is
+ * primarily an attempt to externalize state for a component so that it can be recorded outside the
+ * object.
+ * <p>
+ * ComponentActions should be immutable. They are often created during one request and associated
+ * with a particular component instance. They are then used in a later request (with an equivalent
+ * component instance).
+ * <p>
+ * ComponentActions are serializable (they are often serialized into Base64 strings for storage on
+ * the client).
+ */
+public interface ComponentAction<T> extends Serializable
+{
+    /** Passed a component instance, the action should operate upon the instance. */
+    void execute(T component);
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentResourcesCommon.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentResourcesCommon.java?view=diff&rev=471463&r1=471462&r2=471463
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentResourcesCommon.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentResourcesCommon.java Sun Nov  5 09:01:19 2006
@@ -17,6 +17,7 @@
 import org.apache.commons.logging.Log;
 import org.apache.tapestry.internal.structure.ComponentPageElement;
 import org.apache.tapestry.model.ComponentModel;
+import org.apache.tapestry.services.ComponentSource;
 
 /**
  * Operations shared by {@link ComponentResources} and {@link ComponentPageElement}.
@@ -51,9 +52,13 @@
     Link createActionLink(String action, boolean forForm, Object... context);
 
     /**
-     * Returns a string consisting of the class name of the containing page, and the
+     * Returns a string consisting of the fully qualified class name of the containing page, and the
      * {@link #getNestedId() nested id} of this component, separated by a colon. I.e.,
      * "com.foo.pages.MyPage:foo.bar.baz". For a page, returns just the page class name.
+     * <p>
+     * This value is often used to obtain an equivalent component instance in a later request.
+     * 
+     * @see ComponentSource
      */
 
     String getCompleteId();

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/Field.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/Field.java?view=auto&rev=471463
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/Field.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/Field.java Sun Nov  5 09:01:19 2006
@@ -0,0 +1,34 @@
+// 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;
+
+/**
+ * Defines a field within a form.
+ */
+public interface Field
+{
+    /**
+     * Returns the value used as the name attribute of the rendered element. This value will be
+     * unique within an enclosing form, even if the same component renders multiple times.
+     */
+    String getElementName();
+
+    /**
+     * Returns a unique id for the element. This value will be unique for any given rendering of a
+     * page. This value is intended for use as the id attribute of the client-side element, and will
+     * be used with any DHTML/Ajax related JavaScript.
+     */
+    String getClientId();
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/Link.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/Link.java?view=diff&rev=471463&r1=471462&r2=471463
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/Link.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/Link.java Sun Nov  5 09:01:19 2006
@@ -44,9 +44,24 @@
 
     String getParameterValue(String name);
 
+    /**
+     * Adds a parameter value.
+     * 
+     * @param parameterName
+     *            the name of the parameter to store
+     * @param value
+     *            the value to store
+     * @throws IllegalArgumentException
+     *             if the link already has a parameter with the given name
+     */
+    void addParameter(String parameterName, String value);
+
     /** Returns the link as a normal URI. The URI includes any query parameters. */
     String toURI();
 
     /** Returns the link as a redirect URI. The URI includes any query parameters. */
     String toRedirectURI();
+
+    /** Returns just the path portion of the URI, excluding any query parameters. */
+    String toFormURI();
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/AfterRenderBody.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/AfterRenderBody.java?view=diff&rev=471463&r1=471462&r2=471463
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/AfterRenderBody.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/AfterRenderBody.java Sun Nov  5 09:01:19 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.annotations;
 
 import static java.lang.annotation.RetentionPolicy.RUNTIME;

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/AfterRenderTemplate.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/AfterRenderTemplate.java?view=diff&rev=471463&r1=471462&r2=471463
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/AfterRenderTemplate.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/AfterRenderTemplate.java Sun Nov  5 09:01:19 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.annotations;
 
 import static java.lang.annotation.RetentionPolicy.RUNTIME;

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/BeforeRenderTemplate.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/BeforeRenderTemplate.java?view=diff&rev=471463&r1=471462&r2=471463
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/BeforeRenderTemplate.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/BeforeRenderTemplate.java Sun Nov  5 09:01:19 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.annotations;
 
 import static java.lang.annotation.RetentionPolicy.RUNTIME;

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/AbstractField.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/AbstractField.java?view=auto&rev=471463
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/AbstractField.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/AbstractField.java Sun Nov  5 09:01:19 2006
@@ -0,0 +1,124 @@
+// 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.corelib.components;
+
+import java.io.Serializable;
+
+import org.apache.tapestry.ComponentAction;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.Field;
+import org.apache.tapestry.annotations.ComponentClass;
+import org.apache.tapestry.annotations.Environmental;
+import org.apache.tapestry.annotations.Inject;
+import org.apache.tapestry.annotations.SetupRender;
+import org.apache.tapestry.services.FormSupport;
+import org.apache.tapestry.services.PageRenderSupport;
+import org.apache.tapestry.services.WebRequest;
+
+/** Provides initialization of the clientId and elementName properties. */
+@ComponentClass
+public abstract class AbstractField implements Field
+{
+    static class SetupAction implements ComponentAction<AbstractField>, Serializable
+    {
+        private static final long serialVersionUID = 2690270808212097020L;
+
+        private final String _elementName;
+
+        public SetupAction(final String elementName)
+        {
+            _elementName = elementName;
+        }
+
+        public void execute(AbstractField component)
+        {
+            component.setupElementName(_elementName);
+        }
+    }
+
+    static class ProcessSubmissionAction implements ComponentAction<AbstractField>, Serializable
+    {
+        private static final long serialVersionUID = -4346426414137434418L;
+
+        public void execute(AbstractField component)
+        {
+            component.processSubmission();
+        }
+    }
+
+    /** Used a shared instance for all types of fields, for efficiency. */
+    private static final ProcessSubmissionAction PROCESS_SUBMISSION_ACTION = new ProcessSubmissionAction();
+
+    private String _clientId;
+
+    private String _elementName;
+
+    @Environmental
+    private FormSupport _formSupport;
+
+    @Environmental
+    private PageRenderSupport _pageRenderSupport;
+
+    @Inject
+    private ComponentResources _resources;
+
+    @Inject("infrastructure:request")
+    private WebRequest _request;
+
+    @SetupRender
+    final void setup()
+    {
+        String id = _resources.getId();
+
+        // Often, these will end up as the same value. There are many exceptions, including a form
+        // that renders inside a loop.
+
+        _clientId = _pageRenderSupport.allocateClientId(id);
+        String elementName = _formSupport.allocateElementName(id);
+
+        _formSupport.storeAndExecute(this, new SetupAction(elementName));
+        _formSupport.store(this, PROCESS_SUBMISSION_ACTION);
+    }
+
+    public final String getClientId()
+    {
+        return _clientId;
+    }
+
+    public final String getElementName()
+    {
+        return _elementName;
+    }
+
+    private void setupElementName(String elementName)
+    {
+        _elementName = elementName;
+    }
+
+    private final void processSubmission()
+    {
+        processSubmission(_request);
+    }
+
+    /**
+     * Method implemented by subclasses to actually do the work of processing the submission of the
+     * form. The element's elementName property will already have been set.
+     * 
+     * @param request
+     *            the current request, presumably so that the component may extract a quert
+     *            parameter value that matches the component's element name.
+     */
+    protected abstract void processSubmission(WebRequest request);
+}

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/ComponentMessages.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/ComponentMessages.java?view=auto&rev=471463
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/ComponentMessages.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/ComponentMessages.java Sun Nov  5 09:01:19 2006
@@ -0,0 +1,28 @@
+// 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.corelib.components;
+
+import org.apache.tapestry.Messages;
+import org.apache.tapestry.internal.MessagesImpl;
+
+final class ComponentMessages
+{
+    private static final Messages MESSAGES = MessagesImpl.forClass(ComponentMessages.class);
+
+    static String componentActionNotSerializable(String componentId, Throwable cause)
+    {
+        return MESSAGES.format("component-action-not-serializable", componentId, cause);
+    }
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/Form.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/Form.java?view=diff&rev=471463&r1=471462&r2=471463
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/Form.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/Form.java Sun Nov  5 09:01:19 2006
@@ -1,15 +1,51 @@
+// 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.corelib.components;
 
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+
+import org.apache.tapestry.ComponentAction;
 import org.apache.tapestry.ComponentEventHandler;
 import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.Link;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.TapestryConstants;
+import org.apache.tapestry.annotations.AfterRender;
+import org.apache.tapestry.annotations.BeginRender;
 import org.apache.tapestry.annotations.CleanupRender;
 import org.apache.tapestry.annotations.ComponentClass;
+import org.apache.tapestry.annotations.Environmental;
 import org.apache.tapestry.annotations.Inject;
+import org.apache.tapestry.annotations.OnEvent;
 import org.apache.tapestry.annotations.SetupRender;
+import org.apache.tapestry.dom.Element;
 import org.apache.tapestry.internal.util.AcceptVoidEventHandler;
+import org.apache.tapestry.internal.util.Base64ObjectInputStream;
+import org.apache.tapestry.internal.util.Base64ObjectOutputStream;
+import org.apache.tapestry.runtime.ComponentLifecycle;
+import org.apache.tapestry.services.ComponentSource;
 import org.apache.tapestry.services.Environment;
 import org.apache.tapestry.services.FormSupport;
+import org.apache.tapestry.services.PageRenderSupport;
+import org.apache.tapestry.services.WebRequest;
 
+/**
+ * An HTML form, which will enclose other components to render out the various types of fields.
+ */
 @ComponentClass
 public class Form
 {
@@ -19,20 +55,49 @@
      */
     public static final String PREPARE_EVENT = "prepare";
 
+    /** Event type for a notification after the form has submitted. */
+    public static final String SUBMIT = "submit";
+
+    /**
+     * Query parameter name storing form data (the serialized commands needed to process a form
+     * submission).
+     */
+    public static final String FORM_DATA = "t:formdata";
+
     @Inject("infrastructure:environment")
     private Environment _environment;
 
     @Inject
     private ComponentResources _resources;
 
-    private String _componentId = _resources.getId();
+    @Environmental
+    private PageRenderSupport _pageRenderSupport;
+
+    @Inject("infrastructure:request")
+    private WebRequest _request;
+
+    @Inject("infrastructure:componentSource")
+    private ComponentSource _source;
+
+    // Collects a stream of component actions. Each action goes in as a UTF string (the component
+    // component id),
+    // followed by a ComponentAction
+
+    private Base64ObjectOutputStream _actions;
 
     @SetupRender
     void setup()
     {
-        FormSupport support = new FormSupport()
+        try
+        {
+            _actions = new Base64ObjectOutputStream();
+        }
+        catch (IOException ex)
         {
-        };
+            throw new RuntimeException(ex);
+        }
+
+        FormSupport support = new FormSupportImpl(_actions);
 
         // TODO: Forms should not allow to nest. Perhaps a set() method instead of a push() method
         // for this kind of check?
@@ -46,15 +111,101 @@
 
     private void fireNotification(String eventType)
     {
+        // Use the handler that rejects all non-null return values.
+
         ComponentEventHandler handler = new AcceptVoidEventHandler(eventType, _resources
                 .getCompleteId());
 
         _resources.triggerEvent(eventType, null, handler);
     }
 
+    private Element _div;
+
+    @BeginRender
+    void begin(MarkupWriter writer)
+    {
+        String name = _pageRenderSupport.allocateClientId(_resources.getId());
+
+        Link link = _resources.createActionLink(TapestryConstants.DEFAULT_EVENT, true);
+
+        writer.element("form", "name", name, "id", name, "method", "post", "action", link
+                .toFormURI());
+
+        // TODO: Informal parameters
+
+        _div = writer.element("div", "style", "invisible");
+
+        for (String parameterName : link.getParameterNames())
+        {
+            String value = link.getParameterValue(parameterName);
+
+            writer.element("input", "type", "hidden", "name", parameterName, "value", value);
+            writer.end();
+        }
+
+        writer.end(); // div
+
+    }
+
+    @AfterRender
+    void after(MarkupWriter writer)
+    {
+        writer.end(); // form
+
+        // Now, inject into the div the remaining hidden field (the list of actions).
+
+        try
+        {
+            _actions.close();
+        }
+        catch (IOException ex)
+        {
+            throw new RuntimeException(ex);
+        }
+
+        _div.element("input", "type", "hidden", "name", FORM_DATA, "value", _actions.toBase64());
+    }
+
     @CleanupRender
     void cleanup()
     {
         _environment.pop(FormSupport.class);
     }
+
+    @SuppressWarnings("unchecked")
+    @OnEvent("action")
+    void onSubmit()
+    {
+        // TODO: Ajax stuff will eventually mean there are multiple values for this parameter name
+
+        String actionsBase64 = _request.getParameter(FORM_DATA);
+
+        try
+        {
+            ObjectInputStream ois = new Base64ObjectInputStream(actionsBase64);
+
+            while (true)
+            {
+                String componentId = ois.readUTF();
+                ComponentAction action = (ComponentAction) ois.readObject();
+
+                ComponentLifecycle component = _source.getComponent(componentId);
+
+                action.execute(component);
+            }
+        }
+        catch (EOFException ex)
+        {
+            // Expected.
+        }
+        catch (Exception ex)
+        {
+            throw new RuntimeException(ex);
+        }
+
+        // TODO: The return value should be used to control what renders.
+
+        fireNotification(SUBMIT);
+    }
+
 }

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/FormSupportImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/FormSupportImpl.java?view=auto&rev=471463
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/FormSupportImpl.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/FormSupportImpl.java Sun Nov  5 09:01:19 2006
@@ -0,0 +1,75 @@
+// 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.corelib.components;
+
+import static org.apache.tapestry.util.Defense.cast;
+import static org.apache.tapestry.util.Defense.notNull;
+
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+
+import org.apache.tapestry.ComponentAction;
+import org.apache.tapestry.runtime.ComponentLifecycle;
+import org.apache.tapestry.services.FormSupport;
+import org.apache.tapestry.util.IdAllocator;
+
+class FormSupportImpl implements FormSupport
+{
+    private final IdAllocator _idAllocator = new IdAllocator();
+
+    private final ObjectOutputStream _actions;
+
+    public FormSupportImpl(final ObjectOutputStream actions)
+    {
+        _actions = actions;
+    }
+
+    public String allocateElementName(String id)
+    {
+        return _idAllocator.allocateId(id);
+    }
+
+    public <T> void store(T component, ComponentAction<T> action)
+    {
+        ComponentLifecycle lifecycle = cast(component, ComponentLifecycle.class, "component");
+        notNull(action, "action");
+
+        String completeId = lifecycle.getComponentResources().getCompleteId();
+
+        try
+        {
+            // Writing the complete id is not very efficient, but the GZip filter
+            // should help out there.
+            _actions.writeUTF(completeId);
+            _actions.writeObject(action);
+        }
+        catch (IOException ex)
+        {
+            throw new RuntimeException(ComponentMessages.componentActionNotSerializable(
+                    completeId,
+                    ex), ex);
+        }
+    }
+
+    public <T> void storeAndExecute(T component, ComponentAction<T> action)
+    {
+        store(component, action);
+
+        action.execute(component);
+    }
+}
\ No newline at end of file

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/TextField.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/TextField.java?view=auto&rev=471463
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/TextField.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/TextField.java Sun Nov  5 09:01:19 2006
@@ -0,0 +1,46 @@
+// 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.corelib.components;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.annotations.AfterRender;
+import org.apache.tapestry.annotations.BeginRender;
+import org.apache.tapestry.annotations.Parameter;
+import org.apache.tapestry.services.WebRequest;
+
+public class TextField extends AbstractField
+{
+    @Parameter(required = true)
+    private String _value;
+
+    @BeginRender
+    void begin(MarkupWriter writer)
+    {
+        writer.element("input", "type", "text", "name", getElementName(), "id", getClientId(), "value", _value);
+    }
+
+    @AfterRender
+    void after(MarkupWriter writer)
+    {
+        writer.end(); // input
+    }
+
+    @Override
+    protected void processSubmission(WebRequest request)
+    {
+        _value = request.getParameter(getElementName());
+    }
+
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/dom/Element.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/dom/Element.java?view=diff&rev=471463&r1=471462&r2=471463
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/dom/Element.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/dom/Element.java Sun Nov  5 09:01:19 2006
@@ -69,7 +69,7 @@
      *            the value for the attribute. A value of null is allowed, and no attribute will be
      *            added to the element.
      */
-    public void addAttribute(String name, String value)
+    public void attribute(String name, String value)
     {
         notBlank(name, "name");
 
@@ -83,12 +83,41 @@
             _attributes.put(name, value);
     }
 
-    /** Creates and returns a new Element node as a child of this node. */
-    public Element element(String name)
+    /**
+     * Convienience for invoking {@link #attribute(String, String)} multiple times.
+     * 
+     * @param namesAndValues
+     *            alternating attribute names and attribute values
+     */
+    public void attributes(String... namesAndValues)
+    {
+        int i = 0;
+        while (i < namesAndValues.length)
+        {
+            String name = namesAndValues[i++];
+            String value = namesAndValues[i++];
+
+            attribute(name, value);
+        }
+    }
+
+    /**
+     * Creates and returns a new Element node as a child of this node.
+     * 
+     * @param name
+     *            the name of the element to create
+     * @param namesAndValues
+     *            alternating attribute names and attribute values
+     */
+    public Element element(String name, String... namesAndValues)
     {
         notBlank(name, "name");
 
-        return newChild(new Element(this, name));
+        Element child = newChild(new Element(this, name));
+
+        child.attributes(namesAndValues);
+
+        return child;
     }
 
     public Comment comment(String text)

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentEventDispatcher.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentEventDispatcher.java?view=diff&rev=471463&r1=471462&r2=471463
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentEventDispatcher.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentEventDispatcher.java Sun Nov  5 09:01:19 2006
@@ -70,7 +70,7 @@
         for (int i = 1; i < chunks.length; i++)
             context[i - 1] = chunks[i];
 
-        ComponentPageElement element = page.getComponentByNestedId(nestedComponentId);
+        ComponentPageElement element = page.getComponentElementByNestedId(nestedComponentId);
 
         ComponentEventHandler handler = new ComponentEventHandler()
         {

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentSourceImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentSourceImpl.java?view=auto&rev=471463
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentSourceImpl.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentSourceImpl.java Sun Nov  5 09:01:19 2006
@@ -0,0 +1,49 @@
+// 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.internal.structure.Page;
+import org.apache.tapestry.runtime.ComponentLifecycle;
+import org.apache.tapestry.services.ComponentSource;
+
+public class ComponentSourceImpl implements ComponentSource
+{
+    private final RequestPageCache _pageCache;
+
+    public ComponentSourceImpl(RequestPageCache pageCache)
+    {
+        _pageCache = pageCache;
+    }
+
+    public ComponentLifecycle getComponent(String componentId)
+    {
+        int colonx = componentId.indexOf(':');
+
+        if (colonx < 0)
+        {
+            Page page = _pageCache.getByClassName(componentId);
+
+            return page.getRootElement().getComponent();
+        }
+
+        String pageName = componentId.substring(0, colonx);
+
+        Page page = _pageCache.getByClassName(pageName);
+        String nestedId = componentId.substring(colonx + 1);
+
+        return page.getComponentElementByNestedId(nestedId).getComponent();
+    }
+
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/LinkImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/LinkImpl.java?view=diff&rev=471463&r1=471462&r2=471463
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/LinkImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/LinkImpl.java Sun Nov  5 09:01:19 2006
@@ -14,10 +14,15 @@
 
 package org.apache.tapestry.internal.services;
 
-import java.util.Collections;
+import static org.apache.tapestry.util.CollectionFactory.newMap;
+
 import java.util.List;
+import java.util.Map;
 
+import org.apache.commons.codec.EncoderException;
+import org.apache.commons.codec.net.URLCodec;
 import org.apache.tapestry.Link;
+import org.apache.tapestry.internal.util.InternalUtils;
 import org.apache.tapestry.services.WebResponse;
 
 /**
@@ -29,30 +34,87 @@
 
     private final String _path;
 
+    private Map<String, String> _parameters;
+
     public LinkImpl(WebResponse response, String path)
     {
         _response = response;
         _path = path;
     }
 
+    public void addParameter(String parameterName, String value)
+    {
+        if (_parameters == null)
+            _parameters = newMap();
+
+        if (_parameters.containsKey(parameterName))
+            throw new IllegalArgumentException(ServicesMessages.parameterNameMustBeUnique(
+                    parameterName,
+                    _parameters.get(parameterName)));
+
+        _parameters.put(parameterName, value);
+    }
+
+    public String toFormURI()
+    {
+        return _response.encodeURL(_path);
+    }
+
     public List<String> getParameterNames()
     {
-        return Collections.emptyList();
+        return InternalUtils.sortedKeys(_parameters);
     }
 
     public String getParameterValue(String name)
     {
-        return null;
+        return InternalUtils.get(_parameters, name);
     }
 
     public String toURI()
     {
-        return _response.encodeURL(_path);
+        return _response.encodeURL(buildURI());
     }
 
-    public String toRedirectURI()
+    private String buildURI()
     {
-        return _response.encodeRedirectURL(_path);
+        if (_parameters == null)
+            return _path;
+
+        StringBuilder builder = new StringBuilder();
+
+        builder.append(_path);
+
+        try
+        {
+            URLCodec codec = new URLCodec();
+
+            String sep = "?";
+
+            for (String name : getParameterNames())
+            {
+                String value = _parameters.get(name);
+
+                builder.append(sep);
+
+                // TODO: encode the parameter name?
+
+                builder.append(name);
+                builder.append("=");
+                builder.append(codec.encode(value));
+
+                sep = "&";
+            }
+        }
+        catch (EncoderException ex)
+        {
+            throw new RuntimeException(ex);
+        }
+
+        return builder.toString();
     }
 
+    public String toRedirectURI()
+    {
+        return _response.encodeRedirectURL(buildURI());
+    }
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/MarkupWriterImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/MarkupWriterImpl.java?view=diff&rev=471463&r1=471462&r2=471463
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/MarkupWriterImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/MarkupWriterImpl.java Sun Nov  5 09:01:19 2006
@@ -80,7 +80,7 @@
             if (value == null)
                 continue;
 
-            _current.addAttribute(name, value.toString());
+            _current.attribute(name, value.toString());
         }
 
     }

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageRenderSupportImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageRenderSupportImpl.java?view=auto&rev=471463
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageRenderSupportImpl.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageRenderSupportImpl.java Sun Nov  5 09:01:19 2006
@@ -0,0 +1,29 @@
+// 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.services.PageRenderSupport;
+import org.apache.tapestry.util.IdAllocator;
+
+public class PageRenderSupportImpl implements PageRenderSupport
+{
+    private final IdAllocator _idAllocator = new IdAllocator();
+
+    public String allocateClientId(String id)
+    {
+        return _idAllocator.allocateId(id);
+    }
+
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RequestPageCache.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RequestPageCache.java?view=diff&rev=471463&r1=471462&r2=471463
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RequestPageCache.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RequestPageCache.java Sun Nov  5 09:01:19 2006
@@ -18,8 +18,6 @@
 
 /**
  * Per-thread service that caches page instances for the duration of the request.
- * 
- * 
  */
 public interface RequestPageCache
 {
@@ -35,4 +33,16 @@
      *             if the name can not be resolved to a page instance
      */
     Page get(String pageName);
+
+    /**
+     * Gets the page via its fully qualified class name, in the current locale.
+     * 
+     * @param pageName
+     *            fully qualified class name
+     * @return a page instance reserved for this request
+     * @throws RuntimeException
+     *             if the name can not be resolved to a page instance
+     */
+    Page getByClassName(String className);
+
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RequestPageCacheImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RequestPageCacheImpl.java?view=diff&rev=471463&r1=471462&r2=471463
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RequestPageCacheImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RequestPageCacheImpl.java Sun Nov  5 09:01:19 2006
@@ -49,6 +49,11 @@
         if (className == null)
             throw new RuntimeException(ServicesMessages.pageDoesNotExist(pageName));
 
+        return getByClassName(className);
+    }
+
+    public Page getByClassName(String className)
+    {
         Page page = _cache.get(className);
 
         if (page == null)

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=471463&r1=471462&r2=471463
==============================================================================
--- 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 Sun Nov  5 09:01:19 2006
@@ -225,4 +225,9 @@
     {
         return MESSAGES.format("could-not-resolve-mixin-type", mixinType);
     }
+
+    static String parameterNameMustBeUnique(String parameterName, String parameterValue)
+    {
+        return MESSAGES.format("parameter-name-must-be-unique", parameterName, parameterValue);
+    }
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java?view=diff&rev=471463&r1=471462&r2=471463
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java Sun Nov  5 09:01:19 2006
@@ -157,10 +157,21 @@
         }
         else
         {
-            String containerId = _container.getNestedId();
+            String parentNestedId = container.getNestedId();
 
-            _nestedId = containerId == null ? id : containerId + "." + id;
-            _completeId = componentClassName + ":" + _nestedId;
+            // The root element has no nested id.
+            // The children of the root element have an id.
+
+            if (parentNestedId == null)
+            {
+                _nestedId = id;
+                _completeId = _page.getName() + ":" + id;
+            }
+            else
+            {
+                _nestedId = parentNestedId + "." + id;
+                _completeId = container.getCompleteId() + "." + id;
+            }
         }
     }
 

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/Page.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/Page.java?view=diff&rev=471463&r1=471462&r2=471463
==============================================================================
--- 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 Sun Nov  5 09:01:19 2006
@@ -92,12 +92,12 @@
     Log getLog();
 
     /**
-     * Retrieves a component by its nested id (a sequence of simple ids, separated by dots).
+     * Retrieves a component element by its nested id (a sequence of simple ids, separated by dots).
      * 
      * @throws IllegalArgumentException
      *             if the nestedId does not correspond to a component
      */
-    ComponentPageElement getComponentByNestedId(String nestedId);
+    ComponentPageElement getComponentElementByNestedId(String nestedId);
 
     /**
      * Creates a link that will trigger behavior in a component within the page.

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/PageImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/PageImpl.java?view=diff&rev=471463&r1=471462&r2=471463
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/PageImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/PageImpl.java Sun Nov  5 09:01:19 2006
@@ -61,7 +61,7 @@
         return String.format("Page[%s %s]", _name, _locale);
     }
 
-    public ComponentPageElement getComponentByNestedId(String nestedId)
+    public ComponentPageElement getComponentElementByNestedId(String nestedId)
     {
         ComponentPageElement element = _rootElement;
 

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/util/AcceptVoidEventHandler.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/util/AcceptVoidEventHandler.java?view=diff&rev=471463&r1=471462&r2=471463
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/util/AcceptVoidEventHandler.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/util/AcceptVoidEventHandler.java Sun Nov  5 09:01:19 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.util;
 
 import org.apache.tapestry.ComponentEventHandler;

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/util/Base64InputStream.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/util/Base64InputStream.java?view=diff&rev=471463&r1=471462&r2=471463
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/util/Base64InputStream.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/util/Base64InputStream.java Sun Nov  5 09:01:19 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.util;
 
 import java.io.ByteArrayInputStream;

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/util/Base64ObjectInputStream.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/util/Base64ObjectInputStream.java?view=diff&rev=471463&r1=471462&r2=471463
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/util/Base64ObjectInputStream.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/util/Base64ObjectInputStream.java Sun Nov  5 09:01:19 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.util;
 
 import java.io.BufferedInputStream;

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/util/Base64ObjectOutputStream.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/util/Base64ObjectOutputStream.java?view=diff&rev=471463&r1=471462&r2=471463
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/util/Base64ObjectOutputStream.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/util/Base64ObjectOutputStream.java Sun Nov  5 09:01:19 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.util;
 
 import java.io.BufferedOutputStream;

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/util/Base64OutputStream.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/util/Base64OutputStream.java?view=diff&rev=471463&r1=471462&r2=471463
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/util/Base64OutputStream.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/util/Base64OutputStream.java Sun Nov  5 09:01:19 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.util;
 
 import java.io.ByteArrayOutputStream;
@@ -16,6 +30,10 @@
 
         byte[] base64 = Base64.encodeBase64(binary);
 
-        return new String(base64);
+        String result = new String(base64);
+
+        // System.out.printf("result = %d characters\n\n", result.length());
+
+        return result;
     }
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java?view=diff&rev=471463&r1=471462&r2=471463
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java Sun Nov  5 09:01:19 2006
@@ -201,6 +201,7 @@
      * <li>Null to Boolean (always false)</li>
      * <li>Collection to Boolean (false if empty)</li>
      * <li>Object to List (by wrapping as a singleton list)</li>
+     * <li>Null to String (still null)</li>
      * </ul>
      * 
      * @see #buildTypeCoercer(Collection, ComponentInstantiatorSource)
@@ -213,6 +214,15 @@
             public String coerce(Object input)
             {
                 return input.toString();
+            }
+        });
+
+        add(configuration, void.class, String.class, new Coercion<Void, String>()
+        {
+
+            public String coerce(Void input)
+            {
+                return null;
             }
         });
 

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/ComponentSource.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/ComponentSource.java?view=auto&rev=471463
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/ComponentSource.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/ComponentSource.java Sun Nov  5 09:01:19 2006
@@ -0,0 +1,38 @@
+// 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.services;
+
+import org.apache.tapestry.ComponentResourcesCommon;
+import org.apache.tapestry.runtime.ComponentLifecycle;
+
+/**
+ * Used by classes that need to retrieve a component by its complete id. The complete id is the FQCN
+ * of the containing page, a colon, and the nested component id. It may also just be the page name
+ * (for the root component of a page).
+ */
+public interface ComponentSource
+{
+    /**
+     * Gets a component by its id.
+     * 
+     * @param componentId
+     *            complete component id
+     * @return the component
+     * @throws IllegalArgumentException
+     *             if the component can not be found
+     * @see ComponentResourcesCommon#getCompleteId()
+     */
+    ComponentLifecycle getComponent(String componentId);
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/FormSupport.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/FormSupport.java?view=diff&rev=471463&r1=471462&r2=471463
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/FormSupport.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/FormSupport.java Sun Nov  5 09:01:19 2006
@@ -14,6 +14,8 @@
 
 package org.apache.tapestry.services;
 
+import org.apache.tapestry.ComponentAction;
+
 /**
  * Services provided by an enclosing Form control component to the various form element components
  * it encloses.
@@ -22,5 +24,19 @@
  */
 public interface FormSupport
 {
+    /**
+     * Allocates a unique (within the form) element name for some component enclosed component,
+     * based on the component's id.
+     * 
+     * @param id
+     *            the component's id
+     * @return a unique string, usually the component's id, but sometime extended with a unique
+     *         number or string
+     */
+    String allocateElementName(String id);
 
+    /**  Stores an action for execution during a later request. */
+    <T> void store(T component, ComponentAction<T> action);
+    
+    <T> void storeAndExecute(T component, ComponentAction<T> action);
 }

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/PageRenderSupport.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/PageRenderSupport.java?view=auto&rev=471463
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/PageRenderSupport.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/PageRenderSupport.java Sun Nov  5 09:01:19 2006
@@ -0,0 +1,36 @@
+// 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.services;
+
+import org.apache.tapestry.util.IdAllocator;
+
+/**
+ * Provides support to all components that render. This is primarily about generating unique
+ * client-side ids (very important for JavaScript generation) as well as accumulating JavaScript to
+ * be sent to the client.
+ */
+public interface PageRenderSupport
+{
+    /**
+     * Allocates a unique id based on the component's id. In some cases, the return value will not
+     * precisely match the input value (an underscore and a unique index value may be appended).
+     * 
+     * @param id
+     *            the component id from which a unique id will be generated
+     * @return a unqiue id for this rendering of the page
+     * @see IdAllocator
+     */
+    String allocateClientId(String id);
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java?view=diff&rev=471463&r1=471462&r2=471463
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java Sun Nov  5 09:01:19 2006
@@ -44,6 +44,7 @@
 import org.apache.tapestry.internal.services.ComponentInstantiatorSource;
 import org.apache.tapestry.internal.services.ComponentLifecycleMethodWorker;
 import org.apache.tapestry.internal.services.ComponentResourcesInjectionProvider;
+import org.apache.tapestry.internal.services.ComponentSourceImpl;
 import org.apache.tapestry.internal.services.ComponentWorker;
 import org.apache.tapestry.internal.services.DefaultInjectionProvider;
 import org.apache.tapestry.internal.services.EnvironmentImpl;
@@ -58,6 +59,7 @@
 import org.apache.tapestry.internal.services.MixinWorker;
 import org.apache.tapestry.internal.services.OnEventWorker;
 import org.apache.tapestry.internal.services.PageRenderDispatcher;
+import org.apache.tapestry.internal.services.PageRenderSupportImpl;
 import org.apache.tapestry.internal.services.PageResponseRenderer;
 import org.apache.tapestry.internal.services.ParameterWorker;
 import org.apache.tapestry.internal.services.PersistWorker;
@@ -113,6 +115,8 @@
 
     private final WebRequest _request;
 
+    private final Environment _environment;
+
     // Yes, you can inject services defined by this module into this module. The service proxy is
     // created without instantiating the module itself. We're careful about making as many
     // service builder and contributor methods static as possible to avoid recursive build
@@ -126,7 +130,8 @@
     ChainBuilder chainBuilder, @InjectService("tapestry.internal.RequestPageCache")
     RequestPageCache requestPageCache, @InjectService("tapestry.internal.PageResponseRenderer")
     PageResponseRenderer pageResponseRenderer, @Inject("infrastructure:request")
-    WebRequest request)
+    WebRequest request, @InjectService("Environment")
+    Environment environment)
     {
         _pipelineBuilder = pipelineBuilder;
         _shadowBuilder = shadowBuilder;
@@ -136,6 +141,7 @@
         _requestPageCache = requestPageCache;
         _pageResponseRenderer = pageResponseRenderer;
         _request = request;
+        _environment = environment;
     }
 
     private static <T> void add(Configuration<InfrastructureContribution> configuration,
@@ -372,7 +378,8 @@
         add(configuration, locator, MarkupWriterFactory.class);
         add(configuration, locator, PersistentFieldManager.class);
         add(configuration, locator, Environment.class);
-
+        add(configuration, locator, ComponentSource.class);
+        
         configuration.add(new InfrastructureContribution("request", request));
         configuration.add(new InfrastructureContribution("response", response));
         configuration.add(new InfrastructureContribution("typeCoercer", typeCoercer));
@@ -570,15 +577,13 @@
      * {@link Environment}. The Environment is cleared before any of the contributions are
      * executed.
      */
-    public static Runnable buildPageRenderInitializer(final Collection<Runnable> configuration,
-            @InjectService("Environment")
-            final Environment environment)
+    public Runnable buildPageRenderInitializer(final Collection<Runnable> configuration)
     {
         return new Runnable()
         {
             public void run()
             {
-                environment.clear();
+                _environment.clear();
 
                 for (Runnable r : configuration)
                     r.run();
@@ -586,6 +591,21 @@
         };
     }
 
+    public void contributePageRenderInitializer(Configuration<Runnable> configuration)
+    {
+        // I'm not happy with this lifecycle, per-se. Instead of Runnable, I think we need an
+        // interface more tailored to Environment, with perhaps a second method for the end of
+        // the page render.
+
+        configuration.add(new Runnable()
+        {
+            public void run()
+            {
+                _environment.push(PageRenderSupport.class, new PageRenderSupportImpl());
+            }
+        });
+    }
+
     /** A public service since extensions may provide new persistent strategies. */
     public static PersistentFieldManager buildPersistentFieldManager(
             Map<String, PersistentFieldStrategy> configuration)
@@ -600,5 +620,12 @@
             MappedConfiguration<String, PersistentFieldStrategy> configuration)
     {
         configuration.add("session", new SessionPersistentFieldStrategy(_request));
+    }
+
+    public ComponentSource buildComponentSource(
+            @InjectService("tapestry.internal.RequestPageCache")
+            RequestPageCache pageCache)
+    {
+        return new ComponentSourceImpl(pageCache);
     }
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/TestBase.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/TestBase.java?view=diff&rev=471463&r1=471462&r2=471463
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/TestBase.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/TestBase.java Sun Nov  5 09:01:19 2006
@@ -38,7 +38,7 @@
         @Override
         protected IMocksControl initialValue()
         {
-            return EasyMock.createNiceControl();
+            return EasyMock.createControl();
         }
     }
 
@@ -62,8 +62,8 @@
     }
 
     /**
-     * Creates a new mock object of the indicated type. Creates a <em>strict</em> mock, which
-     * enforces an exact order of method invocation.
+     * Creates a new mock object of the indicated type. The shared mock control does <strong>not</strong>
+     * check order, but does fail on any unexpected method invocations.
      * 
      * @param <T>
      *            the type of the mock object

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/corelib/components/ComponentStrings.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/corelib/components/ComponentStrings.properties?view=auto&rev=471463
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/corelib/components/ComponentStrings.properties (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/corelib/components/ComponentStrings.properties Sun Nov  5 09:01:19 2006
@@ -0,0 +1,15 @@
+# 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.
+
+component-action-not-serializable=Error serializing component action for component %s: %s
\ No newline at end of file

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=471463&r1=471462&r2=471463
==============================================================================
--- 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 Sun Nov  5 09:01:19 2006
@@ -55,4 +55,5 @@
 unknown-persistent-field-strategy='%s' is not a defined persistent strategy.  Defined stategies: %s.
 could-not-resolve-page-name=Unable to resolve page '%s' to a component class name.
 could-not-resolve-component-type=Unable to resolve component type '%s' to a component class name.
-could-not-resolve-mixin-type=Unable to resolve mixin type '%s' to a component class name.
\ No newline at end of file
+could-not-resolve-mixin-type=Unable to resolve mixin type '%s' to a component class name.
+parameter-name-must-be-unique=Parameter names are required to be unique.  Parameter '%s' already has the value '%s'.
\ No newline at end of file

Modified: tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/infrastructure.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/infrastructure.apt?view=diff&rev=471463&r1=471462&r2=471463
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/infrastructure.apt (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/infrastructure.apt Sun Nov  5 09:01:19 2006
@@ -49,6 +49,8 @@
 *-----------------------+--------------------------------------------------------------------+------------------------------------+
 | <<Property>>          | <<Service Interface>>                                             | <<Default Service>>               |
 *-----------------------+--------------------------------------------------------------------+-----------------------------------+
+| componentSource | {{{../apidocs/org/apache/tapestry/services/ComponentSource.html}ComponentSource}} | tapestry.ComponentSource |
+*-----------------------+--------------------------------------------------------------------+-----------------------------------+
 | environment | {{{../apidocs/org/apache/tapestry/services/Environment.html}Environment}} | tapestry.Environment |
 *-----------------------+--------------------------------------------------------------------+-----------------------------------+
 | markupWriterFactory | {{{../apidocs/org/apache/tapestry/services/MarkupWriterFactory.html}MarkupWriterFactory}} | tapestry.MarkupWriterFactory |