blob: 25456026860432349e031e4ab44f402b3a58a4ea [file] [log] [blame]
// Copyright 2004, 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.components;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.hivemind.HiveMind;
import org.apache.tapestry.*;
import org.apache.tapestry.engine.NullWriter;
import org.apache.tapestry.form.AbstractFormComponent;
import org.apache.tapestry.services.DataSqueezer;
/**
* @author mb
*/
public abstract class IfBean extends AbstractFormComponent
{
public static final Log _log = LogFactory.getLog(IfBean.class);
public static final String IF_VALUE_ATTRIBUTE = "org.mb.tapestry.base.IfValue";
private boolean _rendering = false;
private boolean _conditionValue;
public abstract IBinding getConditionValueBinding();
public abstract boolean getCondition();
public abstract boolean getVolatile();
public abstract String getElement();
public abstract boolean getRenderTag();
public abstract IActionListener getListener();
protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle)
{
boolean cycleRewinding = cycle.isRewinding();
// form may be null if component is not located in a form
IForm form = (IForm)cycle.getAttribute(TapestryUtils.FORM_ATTRIBUTE);
// If the cycle is rewinding, but not this particular form,
// then do nothing (don't even render the body).
if (cycleRewinding && form != null && !form.isRewinding())
return;
// get the condition. work with a hidden field if necessary
_conditionValue = evaluateCondition(cycle, form, cycleRewinding);
_rendering = true;
if (!cycleRewinding && form != null && !NullWriter.class.isInstance(writer))
form.setFormFieldUpdating(true);
try
{
// call listener
IActionListener listener = getListener();
if (listener != null)
listener.actionTriggered(this, cycle);
// now render if condition is true
if (_conditionValue)
{
String element = HiveMind.isNonBlank(getElement()) ? getElement() : getTemplateTagName();
boolean render = !cycleRewinding && (getRenderTag() || HiveMind.isNonBlank(getElement()));
if (render)
{
writer.begin(element);
renderInformalParameters(writer, cycle);
renderIdAttribute(writer, cycle);
}
renderBody(writer, cycle);
if (render)
writer.end(element);
}
}
finally
{
_rendering = false;
}
cycle.setAttribute(IF_VALUE_ATTRIBUTE, new Boolean(_conditionValue));
}
/**
* Overriden from {@link AbstractFormComponent} to handle cases where
* we're not being wrapped by a {@link IForm} component.
*
* <p>This is basically a copy of the same method implemented in {@link AbstractComponent}.</p>
*/
protected void generateClientId()
{
String id = getSpecifiedId();
if (id != null && getPage() != null && getPage().getRequestCycle() != null)
setClientId(getPage().getRequestCycle().getUniqueId(TapestryUtils.convertTapestryIdToNMToken(id)));
}
protected boolean evaluateCondition(IRequestCycle cycle, IForm form, boolean cycleRewinding)
{
boolean condition;
if (form == null || getVolatile())
{
condition = getCondition();
}
else
{
// we are in a form and we care -- load/store the condition in a hidden field
String name = form.getElementId(this);
if (!cycleRewinding)
{
condition = getCondition();
writeValue(form, name, condition);
}
else
{
condition = readValue(cycle, name);
}
}
// write condition value if parameter is bound
IBinding conditionValueBinding = getConditionValueBinding();
if (conditionValueBinding != null)
conditionValueBinding.setObject(new Boolean(condition));
return condition;
}
private void writeValue(IForm form, String name, boolean value)
{
String externalValue;
Object booleanValue = new Boolean(value);
try
{
externalValue = getDataSqueezer().squeeze(booleanValue);
}
catch (Exception ex)
{
throw new ApplicationRuntimeException(Tapestry.format("If.unable-to-convert-value",booleanValue), this, null, ex);
}
form.addHiddenValue(name, externalValue);
}
private boolean readValue(IRequestCycle cycle, String name)
{
String submittedValue = cycle.getParameter(name);
_log.debug("readValue() with : " + name + " [" + submittedValue + "]");
try
{
Object valueObject = getDataSqueezer().unsqueeze(submittedValue);
if (!(valueObject instanceof Boolean))
throw new ApplicationRuntimeException(Tapestry.format("If.invalid-condition-type", submittedValue));
return ((Boolean) valueObject).booleanValue();
}
catch (Exception ex)
{
throw new ApplicationRuntimeException(Tapestry.format(
"If.unable-to-convert-string",
submittedValue), this, null, ex);
}
}
public abstract DataSqueezer getDataSqueezer();
public boolean isDisabled()
{
return false;
}
/**
* Returns the value of the condition.
*
* @return the condition value
*/
public boolean getConditionValue()
{
if (!_rendering)
throw Tapestry.createRenderOnlyPropertyException(this, "conditionValue");
return _conditionValue;
}
// Do nothing in those methods, but make the JVM happy
protected void renderFormComponent(IMarkupWriter writer, IRequestCycle cycle)
{
}
protected void rewindFormComponent(IMarkupWriter writer, IRequestCycle cycle)
{
}
/**
* For component can not take focus.
*/
protected boolean getCanTakeFocus()
{
return false;
}
}