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 015package org.apache.tapestry.components; 016 017import org.apache.hivemind.ApplicationRuntimeException; 018import org.apache.hivemind.HiveMind; 019import org.apache.tapestry.IActionListener; 020import org.apache.tapestry.IBinding; 021import org.apache.tapestry.IForm; 022import org.apache.tapestry.IMarkupWriter; 023import org.apache.tapestry.IRequestCycle; 024import org.apache.tapestry.Tapestry; 025import org.apache.tapestry.TapestryUtils; 026import org.apache.tapestry.form.AbstractFormComponent; 027import org.apache.tapestry.services.DataSqueezer; 028 029/** 030 * @author mb 031 */ 032public 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}