001: // Copyright 2007 The Apache Software Foundation
002: //
003: // Licensed under the Apache License, Version 2.0 (the "License");
004: // you may not use this file except in compliance with the License.
005: // You may obtain a copy of the License at
006: //
007: // http://www.apache.org/licenses/LICENSE-2.0
008: //
009: // Unless required by applicable law or agreed to in writing, software
010: // distributed under the License is distributed on an "AS IS" BASIS,
011: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: // See the License for the specific language governing permissions and
013: // limitations under the License.
014:
015: package org.apache.tapestry.corelib.components;
016:
017: import org.apache.tapestry.Binding;
018: import org.apache.tapestry.ComponentAction;
019: import org.apache.tapestry.ComponentResources;
020: import org.apache.tapestry.RadioContainer;
021: import org.apache.tapestry.ValueEncoder;
022: import org.apache.tapestry.annotations.Environmental;
023: import org.apache.tapestry.annotations.Inject;
024: import org.apache.tapestry.annotations.Parameter;
025: import org.apache.tapestry.internal.TapestryInternalUtils;
026: import org.apache.tapestry.services.ComponentDefaultProvider;
027: import org.apache.tapestry.services.Environment;
028: import org.apache.tapestry.services.FormSupport;
029: import org.apache.tapestry.services.Request;
030: import org.apache.tapestry.services.ValueEncoderSource;
031:
032: public class RadioGroup {
033: /**
034: * The property read and updated by the group as a whole.
035: */
036: @Parameter(required=true,principal=true)
037: private Object _value;
038:
039: /**
040: * If true, then the field will render out with a disabled attribute (to turn off client-side
041: * behavior). Further, a disabled field ignores any value in the request when the form is
042: * submitted.
043: */
044: @Parameter("false")
045: private boolean _disabled;
046:
047: /**
048: * Allows a specific implementation of {@link ValueEncoder} to be supplied. This is used to
049: * create client-side string values for the different radio button values.
050: *
051: * @see ValueEncoderSource
052: */
053: @Parameter(required=true)
054: private ValueEncoder _encoder;
055:
056: @Inject
057: private ComponentDefaultProvider _defaultProvider;
058:
059: @Inject
060: private ComponentResources _resources;
061:
062: @Environmental
063: private FormSupport _formSupport;
064:
065: @Inject
066: private Environment _environment;
067:
068: @Inject
069: private ValueEncoderSource _valueEncoderSource;
070:
071: @Inject
072: private Request _request;
073:
074: private String _elementName;
075:
076: final Binding defaultValue() {
077: return _defaultProvider.defaultBinding("value", _resources);
078: }
079:
080: final ValueEncoder defaultEncoder() {
081: return _valueEncoderSource.createEncoder("value", _resources);
082: }
083:
084: private static class Setup implements ComponentAction<RadioGroup> {
085: private static final long serialVersionUID = -7984673040135949374L;
086:
087: private final String _elementName;
088:
089: Setup(String elementName) {
090: _elementName = elementName;
091: }
092:
093: public void execute(RadioGroup component) {
094: component.setup(_elementName);
095: }
096: };
097:
098: private static final ComponentAction<RadioGroup> PROCESS_SUBMISSION = new ComponentAction<RadioGroup>() {
099: private static final long serialVersionUID = -3857110108918776386L;
100:
101: public void execute(RadioGroup component) {
102: component.processSubmission();
103: }
104: };
105:
106: private void setup(String elementName) {
107: _elementName = elementName;
108: }
109:
110: private void processSubmission() {
111: String clientValue = _request.getParameter(_elementName);
112:
113: Object value = _encoder.toValue(clientValue);
114:
115: _value = value;
116: }
117:
118: /**
119: * Obtains the element name for the group, and stores a {@link RadioContainer} into the
120: * {@link Environment} (so that the {@link Radio} components can find it).
121: */
122: final void setupRender() {
123: String name = _formSupport.allocateElementName(_resources
124: .getId());
125:
126: ComponentAction<RadioGroup> action = new Setup(name);
127:
128: _formSupport.storeAndExecute(this , action);
129:
130: _environment.push(RadioContainer.class, new RadioContainer() {
131: public String getElementName() {
132: return _elementName;
133: }
134:
135: public boolean isDisabled() {
136: return _disabled;
137: }
138:
139: @SuppressWarnings("unchecked")
140: public String toClient(Object value) {
141: // TODO: Ensure that value is of the expected type?
142:
143: return _encoder.toClient(value);
144: }
145:
146: public boolean isSelected(Object value) {
147: return TapestryInternalUtils.isEqual(value, _value);
148: }
149:
150: });
151:
152: _formSupport.store(this , PROCESS_SUBMISSION);
153: }
154:
155: /**
156: * Pops the {@link RadioContainer}.
157: */
158: final void afterRender() {
159: _environment.pop(RadioContainer.class);
160: }
161:
162: }
|