Home » tapestry-src-5.0.19 » org.apache.tapestry5.corelib.components » [javadoc | source]

    1   // Copyright 2007, 2008 The Apache Software Foundation
    2   //
    3   // Licensed under the Apache License, Version 2.0 (the "License");
    4   // you may not use this file except in compliance with the License.
    5   // You may obtain a copy of the License at
    6   //
    7   //     http://www.apache.org/licenses/LICENSE-2.0
    8   //
    9   // Unless required by applicable law or agreed to in writing, software
   10   // distributed under the License is distributed on an "AS IS" BASIS,
   11   // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   12   // See the License for the specific language governing permissions and
   13   // limitations under the License.
   14   
   15   package org.apache.tapestry5.corelib.components;
   16   
   17   import org.apache.tapestry5;
   18   import org.apache.tapestry5.annotations.Environmental;
   19   import org.apache.tapestry5.annotations.Parameter;
   20   import org.apache.tapestry5.internal.TapestryInternalUtils;
   21   import org.apache.tapestry5.ioc.annotations.Inject;
   22   import org.apache.tapestry5.services.ComponentDefaultProvider;
   23   import org.apache.tapestry5.services.Environment;
   24   import org.apache.tapestry5.services.FormSupport;
   25   import org.apache.tapestry5.services.Request;
   26   
   27   public class RadioGroup implements Field
   28   {
   29       /**
   30        * The property read and updated by the group as a whole.
   31        */
   32       @Parameter(required = true, principal = true, autoconnect = true)
   33       private Object value;
   34   
   35       /**
   36        * If true, then the field will render out with a disabled attribute (to turn off client-side behavior). Further, a
   37        * disabled field ignores any value in the request when the form is submitted.
   38        */
   39       @Parameter("false")
   40       private boolean disabled;
   41   
   42       /**
   43        * The user presentable label for the field. If not provided, a reasonable label is generated from the component's
   44        * id, first by looking for a message key named "id-label" (substituting the component's actual id), then by
   45        * converting the actual id to a presentable string (for example, "userId" to "User Id").
   46        */
   47       @Parameter(defaultPrefix = BindingConstants.LITERAL)
   48       private String label;
   49   
   50       /**
   51        * The id used to generate a page-unique client-side identifier for the component. If a component renders multiple
   52        * times, a suffix will be appended to the to id to ensure uniqueness. The uniqued value may be accessed via the
   53        * {@link #getClientId() clientId property}.
   54        */
   55       @Parameter(value = "prop:componentResources.id", defaultPrefix = BindingConstants.LITERAL)
   56       private String clientId;
   57   
   58       /**
   59        * Allows a specific implementation of {@link org.apache.tapestry5.ValueEncoder} to be supplied. This is used to
   60        * create client-side string values for the different radio button values.
   61        */
   62       @Parameter(required = true, allowNull = false)
   63       private ValueEncoder encoder;
   64   
   65       @Inject
   66       private ComponentDefaultProvider defaultProvider;
   67   
   68       @Inject
   69       private ComponentResources resources;
   70   
   71       @Environmental
   72       private FormSupport formSupport;
   73   
   74       @Inject
   75       private Environment environment;
   76   
   77       @Inject
   78       private Request request;
   79   
   80       @Environmental
   81       private ValidationTracker tracker;
   82   
   83       private String controlName;
   84   
   85       String defaultLabel()
   86       {
   87           return defaultProvider.defaultLabel(resources);
   88       }
   89   
   90       final ValueEncoder defaultEncoder()
   91       {
   92           return defaultProvider.defaultValueEncoder("value", resources);
   93       }
   94   
   95       private static class Setup implements ComponentAction<RadioGroup>
   96       {
   97           private static final long serialVersionUID = -7984673040135949374L;
   98   
   99           private final String controlName;
  100   
  101           Setup(String controlName)
  102           {
  103               this.controlName = controlName;
  104           }
  105   
  106           public void execute(RadioGroup component)
  107           {
  108               component.setup(controlName);
  109           }
  110   
  111           @Override
  112           public String toString()
  113           {
  114               return String.format("RadioGroup.Setup[%s]", controlName);
  115           }
  116       }
  117   
  118       private static final ComponentAction<RadioGroup> PROCESS_SUBMISSION = new ComponentAction<RadioGroup>()
  119       {
  120           private static final long serialVersionUID = -3857110108918776386L;
  121   
  122           public void execute(RadioGroup component)
  123           {
  124               component.processSubmission();
  125           }
  126   
  127           @Override
  128           public String toString()
  129           {
  130               return "RadioGroup.ProcessSubmission";
  131           }
  132       };
  133   
  134       private void setup(String elementName)
  135       {
  136           controlName = elementName;
  137       }
  138   
  139       private void processSubmission()
  140       {
  141           String clientValue = request.getParameter(controlName);
  142   
  143           tracker.recordInput(this, clientValue);
  144   
  145           value = encoder.toValue(clientValue);
  146       }
  147   
  148       /**
  149        * Obtains the element name for the group, and stores a {@link RadioContainer} into the {@link Environment} (so that
  150        * the {@link Radio} components can find it).
  151        */
  152       final void setupRender()
  153       {
  154           ComponentAction<RadioGroup> action = new Setup(formSupport.allocateControlName(clientId));
  155   
  156           formSupport.storeAndExecute(this, action);
  157   
  158           String submittedValue = tracker.getInput(this);
  159   
  160           final String selectedValue = submittedValue != null ? submittedValue : encoder.toClient(value);
  161   
  162           environment.push(RadioContainer.class, new RadioContainer()
  163           {
  164               public String getControlName()
  165               {
  166                   return controlName;
  167               }
  168   
  169               public boolean isDisabled()
  170               {
  171                   return disabled;
  172               }
  173   
  174               @SuppressWarnings("unchecked")
  175               public String toClient(Object value)
  176               {
  177                   // TODO: Ensure that value is of the expected type?
  178   
  179                   return encoder.toClient(value);
  180               }
  181   
  182               public boolean isSelected(Object value)
  183               {
  184                   return TapestryInternalUtils.isEqual(encoder.toClient(value), selectedValue);
  185               }
  186           });
  187   
  188           formSupport.store(this, PROCESS_SUBMISSION);
  189       }
  190   
  191       /**
  192        * Pops the {@link RadioContainer} off the Environment.
  193        */
  194       final void afterRender()
  195       {
  196           environment.pop(RadioContainer.class);
  197       }
  198   
  199       public String getControlName()
  200       {
  201           return controlName;
  202       }
  203   
  204       public String getLabel()
  205       {
  206           return label;
  207       }
  208   
  209       public boolean isDisabled()
  210       {
  211           return disabled;
  212       }
  213   
  214       /**
  215        * Returns null; the radio group does not render as a tag and so doesn't have an id to share.  RadioGroup implements
  216        * {@link org.apache.tapestry5.Field} only so it can interact with the {@link org.apache.tapestry5.ValidationTracker}.
  217        *
  218        * @return null
  219        */
  220       public String getClientId()
  221       {
  222           return null;
  223       }
  224   
  225       /**
  226        * Returns false; RadioGroup does not support declarative validation.
  227        */
  228       public boolean isRequired()
  229       {
  230           return false;
  231       }
  232   }

Home » tapestry-src-5.0.19 » org.apache.tapestry5.corelib.components » [javadoc | source]