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.contrib.form; 016 017 import org.apache.hivemind.ApplicationRuntimeException; 018 import org.apache.hivemind.HiveMind; 019 import org.apache.tapestry.AbstractComponent; 020 import org.apache.tapestry.IActionListener; 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.IFormComponent; 027 import org.apache.tapestry.listener.ListenerInvoker; 028 import org.apache.tapestry.services.DataSqueezer; 029 030 /** 031 * A conditional element on a page which will render its wrapped elements zero 032 * or one times. This component is a variant of 033 * {@link org.apache.tapestry.components.Conditional}, but is designed for 034 * operation in a form. The component parameters are stored in hidden fields 035 * during rendering and are taken from those fields during the rewind, thus no 036 * StaleLink exceptions occur. [ <a 037 * href="../../../../../ComponentReference/contrib.FormConditional.html">Component 038 * Reference </a>] 039 * 040 * @author Mindbridge 041 * @since 3.0 042 */ 043 044 public abstract class FormConditional extends AbstractComponent implements 045 IFormComponent 046 { 047 048 protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle) 049 { 050 IForm form = TapestryUtils.getForm(cycle, this); 051 052 boolean cycleRewinding = cycle.isRewinding(); 053 054 // If the cycle is rewinding, but not this particular form, 055 // then do nothing (don't even render the body). 056 057 if (cycleRewinding && !form.isRewinding()) return; 058 059 String name = form.getElementId(this); 060 061 boolean condition = getCondition(cycle, form, name); 062 063 getListenerInvoker().invokeListener(getListener(), this, cycle); 064 065 // render the component body only if the condition is true 066 if (condition) 067 { 068 String element = getElement(); 069 070 boolean render = !cycleRewinding && HiveMind.isNonBlank(element); 071 072 if (render) 073 { 074 writer.begin(element); 075 renderInformalParameters(writer, cycle); 076 } 077 078 renderBody(writer, cycle); 079 080 if (render) writer.end(element); 081 } 082 } 083 084 private boolean getCondition(IRequestCycle cycle, IForm form, String name) 085 { 086 boolean condition; 087 088 if (!cycle.isRewinding()) 089 { 090 condition = getCondition(); 091 writeValue(form, name, condition); 092 } 093 else 094 { 095 String submittedCondition = cycle.getParameter(name); 096 condition = convertValue(submittedCondition); 097 } 098 099 if (isParameterBound("conditionValue")) setConditionValue(condition); 100 101 return condition; 102 } 103 104 private void writeValue(IForm form, String name, boolean value) 105 { 106 String externalValue; 107 108 try 109 { 110 externalValue = getDataSqueezer().squeeze( 111 value ? Boolean.TRUE : Boolean.FALSE); 112 } 113 catch (Exception ex) 114 { 115 throw new ApplicationRuntimeException(Tapestry.format( 116 "FormConditional.unable-to-convert-value", Boolean 117 .toString(value)), this, null, ex); 118 } 119 120 form.addHiddenValue(name, externalValue); 121 } 122 123 private boolean convertValue(String value) 124 { 125 try 126 { 127 Boolean b = (Boolean) getDataSqueezer().unsqueeze(value); 128 return b.booleanValue(); 129 } 130 catch (Exception ex) 131 { 132 throw new ApplicationRuntimeException(Tapestry.format( 133 "FormConditional.unable-to-convert-string", value), this, 134 null, ex); 135 } 136 } 137 138 public abstract DataSqueezer getDataSqueezer(); 139 140 // Part of the FormElement interface. 141 142 public boolean isDisabled() 143 { 144 return false; 145 } 146 147 public abstract boolean getCondition(); 148 149 public abstract void setConditionValue(boolean value); 150 151 public abstract String getElement(); 152 153 public abstract IActionListener getListener(); 154 155 /** 156 * Injected. 157 * 158 * @since 4.0 159 */ 160 161 public abstract ListenerInvoker getListenerInvoker(); 162 163 }