001 /*
002 * Copyright 2011 The Kuali Foundation.
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.kuali.kfs.sys.document.web.renderers;
017
018 import java.io.IOException;
019
020 import javax.servlet.jsp.JspException;
021 import javax.servlet.jsp.JspWriter;
022 import javax.servlet.jsp.PageContext;
023 import javax.servlet.jsp.tagext.Tag;
024
025 import org.apache.struts.taglib.html.HiddenTag;
026 import org.kuali.kfs.sys.businessobject.AccountingLine;
027 import org.kuali.kfs.sys.context.SpringContext;
028 import org.kuali.kfs.sys.document.service.AccountingLineRenderingService;
029 import org.kuali.rice.kns.web.ui.Field;
030 import org.springframework.web.util.HtmlUtils;
031
032 /**
033 * The renderer of an override field
034 */
035 public class OverrideFieldRenderer extends FieldRendererBase {
036 private LabelRenderer overrideLabelRenderer = new LabelRenderer();
037 private FieldRenderer overrideFieldRenderer;
038 private HiddenTag overrideHiddenTag = new HiddenTag();
039 private HiddenTag overrideNeededTag = new HiddenTag();
040 private HiddenTag overridePresentTag = new HiddenTag();
041 private boolean readOnly = false;
042 private String overrideNeededProperty;
043 private String overrideNeededValue;
044 private AccountingLine accountingLine;
045 private String storedFieldValue;
046
047 /**
048 * We never render quick finders on these
049 * @see org.kuali.kfs.sys.document.web.renderers.FieldRenderer#renderQuickfinder()
050 */
051 public boolean renderQuickfinder() {
052 return false;
053 }
054
055 /**
056 * Cleans up the tags used to display this field
057 * @see org.kuali.kfs.sys.document.web.renderers.FieldRendererBase#clear()
058 */
059 @Override
060 public void clear() {
061 super.clear();
062 overrideLabelRenderer.clear();
063 overrideFieldRenderer = null;
064 clearOverrideHiddenTag();
065 clearOverrideNeededTag();
066 overrideNeededProperty = null;
067 overrideNeededValue = null;
068 storedFieldValue = null;
069 }
070
071 /**
072 * Cleans up the hidden that displays information for the override
073 */
074 protected void clearOverrideHiddenTag() {
075 overrideHiddenTag.setPageContext(null);
076 overrideHiddenTag.setParent(null);
077 overrideHiddenTag.setProperty(null);
078 overrideHiddenTag.setValue(null);
079 overridePresentTag.setPageContext(null);
080 overridePresentTag.setParent(null);
081 overridePresentTag.setProperty(null);
082 overridePresentTag.setValue(null);
083 }
084
085 /**
086 * Cleans up the HiddenTag that renders override needed properties
087 */
088 protected void clearOverrideNeededTag() {
089 overrideNeededTag.setPageContext(null);
090 overrideNeededTag.setParent(null);
091 overrideNeededTag.setProperty(null);
092 }
093
094 /**
095 * Also sets the overrideNeededProperty name
096 * @see org.kuali.kfs.sys.document.web.renderers.FieldRendererBase#setField(org.kuali.rice.kns.web.ui.Field)
097 */
098 @Override
099 public void setField(Field overrideField) {
100 super.setField(overrideField);
101 this.overrideNeededProperty = overrideField.getPropertyPrefix()+"."+overrideField.getPropertyName()+"Needed";
102 storedFieldValue = overrideField.getPropertyValue();
103 overrideField.setPropertyValue(null);
104 }
105
106 /**
107 * Gets the readOnly attribute.
108 * @return Returns the readOnly.
109 */
110 public boolean isReadOnly() {
111 return readOnly;
112 }
113
114 /**
115 * Sets the readOnly attribute value.
116 * @param readOnly The readOnly to set.
117 */
118 public void setReadOnly(boolean readOnly) {
119 this.readOnly = readOnly;
120 }
121
122 /**
123 * Gets the overrideNeededValue attribute.
124 * @return Returns the overrideNeededValue.
125 */
126 public String getOverrideNeededValue() {
127 return overrideNeededValue;
128 }
129
130 /**
131 * Sets the overrideNeededValue attribute value.
132 * @param overrideNeededValue The overrideNeededValue to set.
133 */
134 public void setOverrideNeededValue(String overrideNeededValue) {
135 this.overrideNeededValue = overrideNeededValue;
136 }
137
138 /**
139 * Gets the accountingLine attribute.
140 * @return Returns the accountingLine.
141 */
142 public AccountingLine getAccountingLine() {
143 return accountingLine;
144 }
145
146 /**
147 * Sets the accountingLine attribute value.
148 * @param accountingLine The accountingLine to set.
149 */
150 public void setAccountingLine(AccountingLine accountingLine) {
151 this.accountingLine = accountingLine;
152 }
153
154 /**
155 * Renders the override field and its associated override needed field
156 * @see org.kuali.kfs.sys.document.web.renderers.Renderer#render(javax.servlet.jsp.PageContext, javax.servlet.jsp.tagext.Tag)
157 */
158 public void render(PageContext pageContext, Tag parentTag) throws JspException {
159 if ((readOnly && getField().getPropertyValue().equals("Yes")) || overrideNeededValue.equals("Yes")) {
160 renderOverrideAsNonHidden(pageContext, parentTag);
161 if (!readOnly) {
162 renderOverridePresent(pageContext, parentTag);
163 }
164 } else {
165 }
166 }
167
168 /**
169 * @return the HTML for a line break
170 */
171 protected String buildLineBreak() {
172 return "<br />";
173 }
174
175 /**
176 * @return the HTML for a non-breaking space
177 */
178 protected String buildNonBreakingSpace() {
179 return " ";
180 }
181
182 /**
183 * @return builds the opening of the span tag to go around the label
184 */
185 protected String buildLabelSpanOpening() {
186 return "<span style=\"font-weight: normal\">";
187 }
188
189 /**
190 * @return builds the closing of the span tag to go around the label
191 */
192 protected String buildLabelSpanClosing() {
193 return "</span>";
194 }
195
196 /**
197 * Renders the override field as non-hidden (probably a checkbox)
198 * @param pageContext the page context to render to
199 * @param parentTag the tag requesting all this rendering
200 * @throws JspException thrown if rendering fails
201 */
202 protected void renderOverrideAsNonHidden(PageContext pageContext, Tag parentTag) throws JspException {
203 JspWriter out = pageContext.getOut();
204 try {
205 out.write(buildLineBreak());
206 openNoWrapSpan(pageContext, parentTag);
207 out.write(buildLabelSpanOpening());
208 overrideLabelRenderer.setLabel(getField().getFieldLabel());
209 overrideLabelRenderer.setRequired(true);
210 overrideLabelRenderer.setReadOnly(false);
211 overrideLabelRenderer.setLabelFor(getField().getPropertyPrefix()+"."+getField().getPropertyName());
212 overrideLabelRenderer.render(pageContext, parentTag);
213 out.write(buildLabelSpanClosing());
214 out.write(buildNonBreakingSpace());
215 overrideFieldRenderer = readOnly ? new ReadOnlyRenderer() : SpringContext.getBean(AccountingLineRenderingService.class).getFieldRendererForField(getField(), accountingLine);
216 if (overrideFieldRenderer instanceof ReadOnlyRenderer) {
217 ((ReadOnlyRenderer)overrideFieldRenderer).setShouldRenderInquiry(false);
218 out.write(": "); // add a colon to make it prettier
219 // populate the field again
220 getField().setPropertyValue(storedFieldValue);
221 }
222 overrideFieldRenderer.setField(getField());
223 overrideFieldRenderer.setArbitrarilyHighTabIndex(getQuickfinderTabIndex());
224 overrideFieldRenderer.render(pageContext, parentTag);
225 closeNoWrapSpan(pageContext, parentTag);
226 }
227 catch (IOException ioe) {
228 throw new JspException("Difficulty rendering override field", ioe);
229 }
230 }
231
232 /**
233 * Renders the override field as a hidden field
234 * @param pageContext the page context to render to
235 * @param parentTag the tag requesting all this rendering
236 * @throws JspException thrown if rendering fails
237 */
238 protected void renderOverrideAsHidden(PageContext pageContext, Tag parentTag) throws JspException {
239 overrideHiddenTag.setPageContext(pageContext);
240 overrideHiddenTag.setParent(parentTag);
241 overrideHiddenTag.setProperty(getField().getPropertyPrefix()+"."+getField().getPropertyName());
242 if (!readOnly && overrideNeededValue.equals("No")) {
243 overrideHiddenTag.setValue("No");
244 } else {
245 overrideHiddenTag.setValue(HtmlUtils.htmlEscape(getField().getPropertyValue()));
246 }
247 overrideHiddenTag.doStartTag();
248 overrideHiddenTag.doEndTag();
249 }
250
251 /**
252 * Renders the override field as a hidden field
253 * @param pageContext the page context to render to
254 * @param parentTag the tag requesting all this rendering
255 * @throws JspException thrown if rendering fails
256 */
257 protected void renderOverridePresent(PageContext pageContext, Tag parentTag) throws JspException {
258 overridePresentTag.setPageContext(pageContext);
259 overridePresentTag.setParent(parentTag);
260 overridePresentTag.setProperty(getField().getPropertyPrefix()+"."+getField().getPropertyName()+".present");
261 overridePresentTag.setValue("I'm here yo!");
262 overridePresentTag.doStartTag();
263 overridePresentTag.doEndTag();
264 }
265
266 /**
267 * Renders the overrideNeeded field (which is always hidden)
268 * @param pageContext the page context to render to
269 * @param parentTag the tag requesting all this rendering
270 * @throws JspException thrown if rendering fails
271 */
272 protected void renderOverrideNeededField(PageContext pageContext, Tag parentTag) throws JspException {
273 overrideNeededTag.setPageContext(pageContext);
274 overrideNeededTag.setParent(parentTag);
275 overrideNeededTag.setProperty(overrideNeededProperty);
276 overrideNeededTag.setValue(HtmlUtils.htmlEscape(overrideNeededValue));
277 overrideNeededTag.doStartTag();
278 overrideNeededTag.doEndTag();
279 }
280 }