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 2005/01/27 19:40:29 UTC

cvs commit: jakarta-tapestry/framework/src/scripts TestWMLFormComponents.xml TestWMLComponents.xml

hlship      2005/01/27 10:40:29

  Modified:    .        status.xml
               framework/src/java/org/apache/tapestry/form Form.java
               framework/src/java/org/apache/tapestry/util IdAllocator.java
               framework/src/java/org/apache/tapestry
                        TapestryStrings.properties
               src/documentation/content/xdocs dev.xml
               framework/src/java/org/apache/tapestry/services
                        ServiceConstants.java
               framework/src/scripts TestWMLFormComponents.xml
                        TestWMLComponents.xml
  Added:       framework/src/java/org/apache/tapestry/form
                        FormMessages.java FormStrings.properties
  Log:
  Changed to Form to prevent collisions between query parameters supplied by services (in an ILink) and form element ids.
  
  Revision  Changes    Path
  1.56      +4 -0      jakarta-tapestry/status.xml
  
  Index: status.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/status.xml,v
  retrieving revision 1.55
  retrieving revision 1.56
  diff -u -r1.55 -r1.56
  --- status.xml	27 Jan 2005 14:20:45 -0000	1.55
  +++ status.xml	27 Jan 2005 18:40:28 -0000	1.56
  @@ -299,6 +299,10 @@
       
     </action>
   		
  +  <action type="update" dev="HLS">
  +    Changed to Form to prevent collisions between query parameters supplied
  +    by services (in an ILink) and form element ids.
  +  </action>    
   	</release>
   
     	
  
  
  
  1.9       +107 -42   jakarta-tapestry/framework/src/java/org/apache/tapestry/form/Form.java
  
  Index: Form.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/form/Form.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- Form.java	6 Jan 2005 02:17:18 -0000	1.8
  +++ Form.java	27 Jan 2005 18:40:29 -0000	1.9
  @@ -15,10 +15,13 @@
   package org.apache.tapestry.form;
   
   import java.util.ArrayList;
  +import java.util.Arrays;
   import java.util.HashMap;
  +import java.util.HashSet;
   import java.util.Iterator;
   import java.util.List;
   import java.util.Map;
  +import java.util.Set;
   
   import org.apache.hivemind.ApplicationRuntimeException;
   import org.apache.hivemind.HiveMind;
  @@ -37,6 +40,7 @@
   import org.apache.tapestry.engine.IEngineService;
   import org.apache.tapestry.engine.ILink;
   import org.apache.tapestry.html.Body;
  +import org.apache.tapestry.services.ServiceConstants;
   import org.apache.tapestry.util.IdAllocator;
   import org.apache.tapestry.util.StringSplitter;
   import org.apache.tapestry.valid.IValidationDelegate;
  @@ -125,6 +129,15 @@
       private List _hiddenValues;
   
       /**
  +     * @since 3.1
  +     */
  +    private Set _standardReservedIds = new HashSet();
  +
  +    {
  +        _standardReservedIds.addAll(Arrays.asList(ServiceConstants.RESERVED_IDS));
  +    }
  +
  +    /**
        * Returns the currently active {@link IForm}, or null if no form is active. This is a
        * convienience method, the result will be null, or an instance of {@link IForm}, but not
        * necessarily a <code>Form</code>.
  @@ -206,19 +219,21 @@
           {
               if (_allocatedIdIndex >= _allocatedIds.size())
               {
  -                throw new StaleLinkException(Tapestry.format(
  -                        "Form.too-many-ids",
  -                        getExtendedId(),
  -                        Integer.toString(_allocatedIds.size()),
  -                        component.getExtendedId()), this);
  +                throw new StaleLinkException(FormMessages.formTooManyIds(
  +                        this,
  +                        _allocatedIds.size(),
  +                        component), this);
               }
   
               String expected = (String) _allocatedIds.get(_allocatedIdIndex);
   
               if (!result.equals(expected))
  -                throw new StaleLinkException(Tapestry.format("Form.id-mismatch", new Object[]
  -                { getExtendedId(), Integer.toString(_allocatedIdIndex + 1), expected, result,
  -                        component.getExtendedId() }), this);
  +                throw new StaleLinkException(FormMessages.formIdMismatch(
  +                        this,
  +                        _allocatedIdIndex,
  +                        expected,
  +                        result,
  +                        component), this);
           }
           else
           {
  @@ -258,8 +273,7 @@
           super.prepareForRender(cycle);
   
           if (cycle.getAttribute(ATTRIBUTE_NAME) != null)
  -            throw new ApplicationRuntimeException(Tapestry.getMessage("Form.forms-may-not-nest"),
  -                    this, null, null);
  +            throw new ApplicationRuntimeException(FormMessages.formsMayNotNest(), this, null, null);
   
           cycle.setAttribute(ATTRIBUTE_NAME, this);
       }
  @@ -312,13 +326,7 @@
           _allocatedIdIndex = 0;
   
           if (rewound)
  -        {
  -            String storedIdList = cycle.getRequestContext().getParameter(_name);
  -
  -            reconstructAllocatedIds(storedIdList);
  -        }
  -
  -        ILink link = getLink(cycle, actionId);
  +            reconstructAllocatedIds(cycle);
   
           // When rendering, use a nested writer so that an embedded Upload
           // component can force the encoding type.
  @@ -329,19 +337,18 @@
   
           if (renderForm)
           {
  +            ILink link = getLink(cycle, actionId);
  +
               writeAttributes(writer, link);
   
               renderInformalParameters(writer, cycle);
               writer.println();
  -        }
   
  -        // Write the hidden's, or at least, reserve the query parameters
  -        // required by the Gesture.
  +            // Write the hidden's, or at least, reserve the query parameters
  +            // required by the Gesture.
   
  -        writeLinkParameters(writer, link, !renderForm);
  +            String extraIds = writeLinkParameters(writer, link, !renderForm);
   
  -        if (renderForm)
  -        {
               // What's this for? It's part of checking for stale links.
               // We record the list of allocated ids.
               // On rewind, we check that the stored list against which
  @@ -351,6 +358,10 @@
               // of ids will change as well.
   
               writeHiddenField(writer, _name, buildAllocatedIdList());
  +
  +            if (HiveMind.isNonBlank(extraIds))
  +                writeHiddenField(writer, _name, extraIds);
  +
               writeHiddenValues(writer);
   
               nested.close();
  @@ -374,11 +385,8 @@
               {
                   String nextExpectedId = (String) _allocatedIds.get(_allocatedIdIndex);
   
  -                throw new StaleLinkException(Tapestry.format(
  -                        "Form.too-few-ids",
  -                        getExtendedId(),
  -                        Integer.toString(expected - _allocatedIdIndex),
  -                        nextExpectedId), this);
  +                throw new StaleLinkException(FormMessages.formTooFewIds(this, expected
  +                        - _allocatedIdIndex, nextExpectedId), this);
               }
   
               IActionListener listener = getListener();
  @@ -443,8 +451,8 @@
           Body body = Body.get(cycle);
   
           if (body == null)
  -            throw new ApplicationRuntimeException(Tapestry
  -                    .getMessage("Form.needs-body-for-event-handlers"), this, null, null);
  +            throw new ApplicationRuntimeException(FormMessages.formNeedsBodyForEventHandlers(),
  +                    this, null, null);
   
           StringBuffer buffer = new StringBuffer();
   
  @@ -571,22 +579,60 @@
           return service.getLink(cycle, parameter);
       }
   
  -    private void writeLinkParameters(IMarkupWriter writer, ILink link, boolean reserveOnly)
  +    /**
  +     * Writes parameters provided by the {@link ILink}. These parameters define the information
  +     * needed to dispatch the request, plus state information. The names of these parameters must be
  +     * reserved so that conflicts don't occur that could disrupt the request processing. For
  +     * example, if the id 'page' is not reserved, then a conflict could occur with a component whose
  +     * id is 'page'. A certain number of ids are always reserved, and we find any additional ids
  +     * beyond that set.
  +     * 
  +     * @return a list of additional reserved ids (not contained within
  +     *         {@link ServiceConstants#RESERVED_IDS}.
  +     */
  +
  +    private String writeLinkParameters(IMarkupWriter writer, ILink link, boolean reserveOnly)
       {
           String[] names = link.getParameterNames();
           int count = Tapestry.size(names);
   
  +        StringBuffer extraIds = new StringBuffer();
  +        String sep = "";
  +
  +        // All the reserved ids, which are essential for
  +        // dispatching the request, are automatically reserved.
  +        // Thus, if you have a component with an id of 'service', its element id
  +        // will likely be 'service$0'.
  +
  +        preallocateReservedIds();
  +
           for (int i = 0; i < count; i++)
           {
               String name = names[i];
   
               // Reserve the name.
   
  -            _elementIdAllocator.allocateId(name);
  +            if (!_standardReservedIds.contains(name))
  +            {
  +                _elementIdAllocator.allocateId(name);
  +
  +                extraIds.append(sep);
  +                extraIds.append(name);
  +
  +                sep = ",";
  +            }
   
               if (!reserveOnly)
                   writeHiddenFieldsForParameter(writer, link, name);
           }
  +
  +        return extraIds.toString();
  +    }
  +
  +    private void preallocateReservedIds()
  +    {
  +        for (int i = 0; i < ServiceConstants.RESERVED_IDS.length; i++)
  +            _elementIdAllocator.allocateId(ServiceConstants.RESERVED_IDS[i]);
       }
   
       /**
  @@ -656,24 +702,44 @@
       }
   
       /**
  +     * Invoked when rewinding a form to re-initialize the _allocatedIds and _elementIdAllocator.
        * Converts a string passed as a parameter (and containing a comma separated list of ids) back
  -     * into the allocateIds property.
  +     * into the allocateIds property. In addition, return the state of the ID allocater back to
  +     * where it was at the start of the render.
        * 
        * @see #buildAllocatedIdList()
        * @since 3.0
        */
   
  -    protected void reconstructAllocatedIds(String storedIdList)
  +    protected void reconstructAllocatedIds(IRequestCycle cycle)
       {
  -        if (HiveMind.isBlank(storedIdList))
  -            return;
  +        String[] values = cycle.getParameters(_name);
   
           StringSplitter splitter = new StringSplitter(',');
   
  -        String[] ids = splitter.splitToArray(storedIdList);
  +        String renderList = values[0];
  +        if (HiveMind.isNonBlank(renderList))
  +        {
  +
  +            String[] ids = splitter.splitToArray(values[0]);
  +
  +            for (int i = 0; i < ids.length; i++)
  +                _allocatedIds.add(ids[i]);
  +        }
  +
  +        // Now, reconstruct the the initial state of the
  +        // id allocator.
  +
  +        preallocateReservedIds();
   
  -        for (int i = 0; i < ids.length; i++)
  -            _allocatedIds.add(ids[i]);
  +        if (values.length > 1)
  +        {
  +            String extraReservedIds = values[1];
  +            String[] ids = splitter.splitToArray(extraReservedIds);
  +
  +            for (int i = 0; i < ids.length; i++)
  +                _elementIdAllocator.allocateId(ids[i]);
  +        }
       }
   
       public abstract IValidationDelegate getDelegate();
  @@ -699,9 +765,8 @@
       public void setEncodingType(String encodingType)
       {
           if (_encodingType != null && !_encodingType.equals(encodingType))
  -            throw new ApplicationRuntimeException(Tapestry.format(
  -                    "Form.encoding-type-contention",
  -                    getExtendedId(),
  +            throw new ApplicationRuntimeException(FormMessages.encodingTypeContention(
  +                    this,
                       _encodingType,
                       encodingType), this, null, null);
   
  
  
  
  1.1                  jakarta-tapestry/framework/src/java/org/apache/tapestry/form/FormMessages.java
  
  Index: FormMessages.java
  ===================================================================
  // Copyright 2005 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.form;
  
  import org.apache.hivemind.impl.MessageFormatter;
  import org.apache.tapestry.IComponent;
  
  /**
   * @author Howard M. Lewis Ship
   * @since 3.1
   */
  class FormMessages
  {
      private static final MessageFormatter _formatter = new MessageFormatter(FormMessages.class,
              "FormStrings");
  
      public static String formTooManyIds(IComponent form, int actualCount, IComponent component)
      {
          return _formatter.format(
                  "form-too-many-ids",
                  form.getExtendedId(),
                  new Integer(actualCount),
                  component.getExtendedId());
      }
  
      public static String formIdMismatch(IComponent form, int mismatchIndex, String expectedId,
              String actualId, IComponent component)
      {
          return _formatter.format("form-id-mismatch", new Object[]
          { form.getExtendedId(), new Integer(mismatchIndex + 1), expectedId, actualId,
                  component.getExtendedId() });
      }
  
      public static String formsMayNotNest()
      {
          return _formatter.getMessage("forms-may-not-nest");
      }
  
      public static String formTooFewIds(IComponent form, int remainingCount, String nextExpectedId)
      {
          return _formatter.format("form-too-few-ids", form.getExtendedId(), new Integer(remainingCount), nextExpectedId);
      }
  
      public static String formNeedsBodyForEventHandlers()
      {
          return _formatter.getMessage("form-needs-body-for-event-handlers");
      }
  
      public static String encodingTypeContention(IComponent form, String establishedEncodingType,
              String newEncodingType)
      {
          return _formatter.format(
                  "encoding-type-contention",
                  form.getExtendedId(),
                  establishedEncodingType,
                  newEncodingType);
      }
  }
  
  
  1.1                  jakarta-tapestry/framework/src/java/org/apache/tapestry/form/FormStrings.properties
  
  Index: FormStrings.properties
  ===================================================================
  # Copyright 2005 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.
  
  form-too-many-ids=Rewind of form {0} expected only {1} form elements, but an additional id was requested by component {2}.
  form-id-mismatch=Rewind of form {0} expected allocated id #{1} to be ''{2}'', but was ''{3}'' (requested by component {4}).
  forms-may-not-nest=Forms may not be nested.
  form-too-few-ids=Rewind of form {0} expected {1} more form elements, starting with id ''{2}''.
  form-needs-body-for-event-handlers=A Form with event handlers must be enclosed by a Body component.
  encoding-type-contention=Components within Form {0} have requested conflicting encoding types ''{1}'' and ''{2}''.
  
  
  
  
  1.4       +17 -20    jakarta-tapestry/framework/src/java/org/apache/tapestry/util/IdAllocator.java
  
  Index: IdAllocator.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/util/IdAllocator.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- IdAllocator.java	5 Jan 2005 23:17:03 -0000	1.3
  +++ IdAllocator.java	27 Jan 2005 18:40:29 -0000	1.4
  @@ -18,14 +18,12 @@
   import java.util.Map;
   
   /**
  - *  Used to "uniquify" names within a given context.  A base name
  - *  is passed in, and the return value is the base name, or the base name
  - *  extended with a suffix to make it unique.
  - *
  - *  @author Howard Lewis Ship
  - *  @since 3.0
  - *
  - **/
  + * Used to "uniquify" names within a given context. A base name is passed in, and the return value
  + * is the base name, or the base name extended with a suffix to make it unique.
  + * 
  + * @author Howard Lewis Ship
  + * @since 3.0
  + */
   
   public class IdAllocator
   {
  @@ -34,6 +32,7 @@
       private static class NameGenerator
       {
           private String _baseId;
  +
           private int _index;
   
           NameGenerator(String baseId)
  @@ -48,10 +47,9 @@
       }
   
       /**
  -     *  Allocates the id.  Repeated calls for the same name will return
  -     *  "name", "name_0", "name_1", etc.
  -     * 
  -     **/
  +     * Allocates the id. Repeated calls for the same name will return "name", "name$0", "name$1",
  +     * etc.
  +     */
   
       public String allocateId(String name)
       {
  @@ -67,8 +65,8 @@
               result = g.nextId();
   
           // Handle the degenerate case, where a base name of the form "foo$0" has been
  -        // requested.  Skip over any duplicates thus formed.
  -        
  +        // requested. Skip over any duplicates thus formed.
  +
           while (_generatorMap.containsKey(result))
               result = g.nextId();
   
  @@ -76,14 +74,13 @@
   
           return result;
       }
  -    
  +
       /**
  -     *  Clears the allocator, resetting it to freshly allocated state.
  -     * 
  -     **/
  -    
  +     * Clears the allocator, resetting it to freshly allocated state.
  +     */
  +
       public void clear()
       {
           _generatorMap.clear();
       }
  -}
  +}
  \ No newline at end of file
  
  
  
  1.13      +0 -7      jakarta-tapestry/framework/src/java/org/apache/tapestry/TapestryStrings.properties
  
  Index: TapestryStrings.properties
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/TapestryStrings.properties,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- TapestryStrings.properties	6 Jan 2005 02:17:12 -0000	1.12
  +++ TapestryStrings.properties	27 Jan 2005 18:40:29 -0000	1.13
  @@ -155,13 +155,6 @@
   
   AbstractFormComponent.must-be-contained-by-form=This component must be contained within a Form.
   
  -Form.forms-may-not-nest=Forms may not be nested.
  -Form.needs-body-for-event-handlers=A Form with event handlers must be enclosed by a Body component.
  -Form.too-many-ids=Rewind of form {0} expected only {1} form elements, but an additional id was requested by component {2}.
  -Form.too-few-ids=Rewind of form {0} expected {1} more form elements, starting with id ''{2}''.
  -Form.id-mismatch=Rewind of form {0} expected allocated id #{1} to be ''{2}'', but was ''{3}'' (requested by component {4}).
  -Form.encoding-type-contention=Components within Form {0} have requested conflicting encoding types ''{1}'' and ''{2}''.
  -
   ListEdit.unable-to-convert-value=Unable to convert {0} to an external string in ListEdit component.
   ListEdit.unable-to-convert-string=Unable to convert {0} back into an object in ListEdit component.
   
  
  
  
  1.5       +1 -1      jakarta-tapestry/src/documentation/content/xdocs/dev.xml
  
  Index: dev.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/src/documentation/content/xdocs/dev.xml,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- dev.xml	25 Jan 2005 01:30:18 -0000	1.4
  +++ dev.xml	27 Jan 2005 18:40:29 -0000	1.5
  @@ -54,7 +54,7 @@
   
   <section>
       <title>Paul Ferraro</title>
  -    Paul has been an avid Tapestry user since 2002.
  +    <p>Paul has been an avid Tapestry user since 2002.</p>
   </section>
   
   <section>
  
  
  
  1.3       +8 -0      jakarta-tapestry/framework/src/java/org/apache/tapestry/services/ServiceConstants.java
  
  Index: ServiceConstants.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/services/ServiceConstants.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ServiceConstants.java	6 Jan 2005 02:17:15 -0000	1.2
  +++ ServiceConstants.java	27 Jan 2005 18:40:29 -0000	1.3
  @@ -63,4 +63,12 @@
        */
   
       public static final String PARAMETER = "sp";
  +
  +    /**
  +     * A list of all the conttants defined by this class.
  +     * 
  +     * @see org.apache.tapestry.form.Form
  +     */
  +    public static final String[] RESERVED_IDS =
  +    { SERVICE, PAGE, COMPONENT, CONTAINER, SESSION, PARAMETER };
   }
  \ No newline at end of file
  
  
  
  1.4       +6 -1      jakarta-tapestry/framework/src/scripts/TestWMLFormComponents.xml
  
  Index: TestWMLFormComponents.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/scripts/TestWMLFormComponents.xml,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- TestWMLFormComponents.xml	6 Jan 2005 02:17:19 -0000	1.3
  +++ TestWMLFormComponents.xml	27 Jan 2005 18:40:29 -0000	1.4
  @@ -92,6 +92,7 @@
               <match>page</match>
               <match>service</match>
               <match>Go1</match>
  +            <match>Go1</match>
               <match>v</match>
           </assert-output-matches>
   
  @@ -111,6 +112,7 @@
               <match>Rewind</match>
               <match>action</match>
               <match>v</match>
  +            <match>action</match>
               <match>$(v)</match>
           </assert-output-matches>
   
  @@ -122,7 +124,10 @@
           <parameter name="action" value="1"/>
           <parameter name="component" value="h"/>
   
  -        <parameter name="Go1" value="v"/>
  +        <parameter name="Go1">
  +          <value>v</value>
  +          <value>action</value>
  +        </parameter>
           <parameter name="v" value="VVV"/>
   
           <assert-output name="Card">
  
  
  
  1.4       +6 -1      jakarta-tapestry/framework/src/scripts/TestWMLComponents.xml
  
  Index: TestWMLComponents.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/scripts/TestWMLComponents.xml,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- TestWMLComponents.xml	6 Jan 2005 02:17:19 -0000	1.3
  +++ TestWMLComponents.xml	27 Jan 2005 18:40:29 -0000	1.4
  @@ -112,6 +112,7 @@
               <match>page</match>
               <match>service</match>
               <match>Go0</match>
  +            <match>Go0</match>            
               <match>u</match>
               <match>l</match>
           </assert-output-matches>
  @@ -125,6 +126,7 @@
               <match>Home</match>
               <match>action</match>
               <match>u,l</match>
  +            <match>action</match>
               <match>$(username)</match>
               <match>$(l)</match>
           </assert-output-matches>
  @@ -136,7 +138,10 @@
           <parameter name="page" value="Home"/>
           <parameter name="action" value="0"/>
           <parameter name="component" value="go"/>
  -        <parameter name="Go0" value="u,l"/>
  +        <parameter name="Go0">
  +          <value>u,l</value>
  +          <value>action</value>
  +        </parameter>
           <parameter name="u" value="newbie"/>
           <parameter name="l" value="0"/>
   
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org