001 // Copyright 2004, 2005 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.components;
016
017 import org.apache.hivemind.ApplicationRuntimeException;
018 import org.apache.hivemind.HiveMind;
019 import org.apache.tapestry.IActionListener;
020 import org.apache.tapestry.IBinding;
021 import org.apache.tapestry.IForm;
022 import org.apache.tapestry.IMarkupWriter;
023 import org.apache.tapestry.IRequestCycle;
024 import org.apache.tapestry.Tapestry;
025 import org.apache.tapestry.TapestryUtils;
026 import org.apache.tapestry.form.AbstractFormComponent;
027 import org.apache.tapestry.services.DataSqueezer;
028
029 /**
030 * @author mb
031 */
032 public abstract class IfBean extends AbstractFormComponent
033 {
034 public final static String IF_VALUE_ATTRIBUTE = "org.mb.tapestry.base.IfValue";
035
036 public abstract IBinding getConditionValueBinding();
037
038 public abstract boolean getCondition();
039
040 public abstract boolean getVolatile();
041
042 public abstract String getElement();
043
044 public abstract IActionListener getListener();
045
046 private boolean _rendering = false;
047
048 private boolean _conditionValue;
049
050 protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle)
051 {
052 boolean cycleRewinding = cycle.isRewinding();
053
054 // form may be null if component is not located in a form
055 IForm form = (IForm) cycle.getAttribute(TapestryUtils.FORM_ATTRIBUTE);
056
057 // If the cycle is rewinding, but not this particular form,
058 // then do nothing (don't even render the body).
059 if (cycleRewinding && form != null && !form.isRewinding())
060 return;
061
062 // get the condition. work with a hidden field if necessary
063 _conditionValue = evaluateCondition(cycle, form, cycleRewinding);
064 _rendering = true;
065
066 try
067 {
068 // call listener
069 IActionListener listener = getListener();
070 if (listener != null)
071 listener.actionTriggered(this, cycle);
072
073 // now render if condition is true
074 if (_conditionValue)
075 {
076 String element = getElement();
077
078 boolean render = !cycleRewinding && HiveMind.isNonBlank(element);
079
080 if (render)
081 {
082 writer.begin(element);
083 renderInformalParameters(writer, cycle);
084 }
085
086 renderBody(writer, cycle);
087
088 if (render)
089 writer.end(element);
090 }
091 }
092 finally
093 {
094 _rendering = false;
095 }
096
097 cycle.setAttribute(IF_VALUE_ATTRIBUTE, new Boolean(_conditionValue));
098 }
099
100 protected boolean evaluateCondition(IRequestCycle cycle, IForm form, boolean cycleRewinding)
101 {
102 boolean condition;
103
104 if (form == null || getVolatile())
105 {
106 condition = getCondition();
107 }
108 else
109 {
110 // we are in a form and we care -- load/store the condition in a hidden field
111 String name = form.getElementId(this);
112
113 if (!cycleRewinding)
114 {
115 condition = getCondition();
116 writeValue(form, name, condition);
117 }
118 else
119 {
120 condition = readValue(cycle, name);
121 }
122 }
123
124 // write condition value if parameter is bound
125 IBinding conditionValueBinding = getConditionValueBinding();
126 if (conditionValueBinding != null)
127 conditionValueBinding.setObject(new Boolean(condition));
128
129 return condition;
130 }
131
132 private void writeValue(IForm form, String name, boolean value)
133 {
134 String externalValue;
135
136 Object booleanValue = new Boolean(value);
137 try
138 {
139 externalValue = getDataSqueezer().squeeze(booleanValue);
140 }
141 catch (Exception ex)
142 {
143 throw new ApplicationRuntimeException(Tapestry.format(
144 "If.unable-to-convert-value",
145 booleanValue), this, null, ex);
146 }
147
148 form.addHiddenValue(name, externalValue);
149 }
150
151 private boolean readValue(IRequestCycle cycle, String name)
152 {
153 String submittedValue = cycle.getParameter(name);
154
155 try
156 {
157 Object valueObject = getDataSqueezer().unsqueeze(submittedValue);
158 if (!(valueObject instanceof Boolean))
159 throw new ApplicationRuntimeException(Tapestry.format(
160 "If.invalid-condition-type",
161 submittedValue));
162
163 return ((Boolean) valueObject).booleanValue();
164 }
165 catch (Exception ex)
166 {
167 throw new ApplicationRuntimeException(Tapestry.format(
168 "If.unable-to-convert-string",
169 submittedValue), this, null, ex);
170 }
171 }
172
173 public abstract DataSqueezer getDataSqueezer();
174
175 public boolean isDisabled()
176 {
177 return false;
178 }
179
180 /**
181 * Returns the value of the condition
182 *
183 * @return the condition value
184 */
185 public boolean getConditionValue()
186 {
187 if (!_rendering)
188 throw Tapestry.createRenderOnlyPropertyException(this, "conditionValue");
189
190 return _conditionValue;
191 }
192
193 // Do nothing in those methods, but make the JVM happy
194 protected void renderFormComponent(IMarkupWriter writer, IRequestCycle cycle)
195 {
196 }
197
198 protected void rewindFormComponent(IMarkupWriter writer, IRequestCycle cycle)
199 {
200 }
201
202 /**
203 * For component can not take focus.
204 */
205 protected boolean getCanTakeFocus()
206 {
207 return false;
208 }
209 }