001/*
002 * Copyright 2008 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 */
016package org.kuali.ole.sys.document.web.renderers;
017
018import java.io.IOException;
019
020import javax.servlet.jsp.JspException;
021import javax.servlet.jsp.JspWriter;
022import javax.servlet.jsp.PageContext;
023import javax.servlet.jsp.tagext.Tag;
024
025import org.apache.struts.taglib.html.HiddenTag;
026import org.kuali.ole.sys.businessobject.AccountingLine;
027import org.kuali.ole.sys.context.SpringContext;
028import org.kuali.ole.sys.document.service.AccountingLineRenderingService;
029import org.kuali.rice.kns.web.ui.Field;
030import org.springframework.web.util.HtmlUtils;
031
032/**
033 * The renderer of an override field
034 */
035public 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.ole.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.ole.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.ole.sys.document.web.renderers.FieldRendererBase#setField(org.kuali.rice.kns.web.ui.Field)
097     * KRAD Conversion: setting fields
098     */
099    @Override
100    public void setField(Field overrideField) {
101        super.setField(overrideField);
102        this.overrideNeededProperty = overrideField.getPropertyPrefix()+"."+overrideField.getPropertyName()+"Needed";
103        storedFieldValue = overrideField.getPropertyValue();
104        overrideField.setPropertyValue(null);
105    }
106
107    /**
108     * Gets the readOnly attribute. 
109     * @return Returns the readOnly.
110     */
111    public boolean isReadOnly() {
112        return readOnly;
113    }
114
115    /**
116     * Sets the readOnly attribute value.
117     * @param readOnly The readOnly to set.
118     */
119    public void setReadOnly(boolean readOnly) {
120        this.readOnly = readOnly;
121    }
122
123    /**
124     * Gets the overrideNeededValue attribute. 
125     * @return Returns the overrideNeededValue.
126     */
127    public String getOverrideNeededValue() {
128        return overrideNeededValue;
129    }
130
131    /**
132     * Sets the overrideNeededValue attribute value.
133     * @param overrideNeededValue The overrideNeededValue to set.
134     */
135    public void setOverrideNeededValue(String overrideNeededValue) {
136        this.overrideNeededValue = overrideNeededValue;
137    }
138
139    /**
140     * Gets the accountingLine attribute. 
141     * @return Returns the accountingLine.
142     */
143    public AccountingLine getAccountingLine() {
144        return accountingLine;
145    }
146
147    /**
148     * Sets the accountingLine attribute value.
149     * @param accountingLine The accountingLine to set.
150     */
151    public void setAccountingLine(AccountingLine accountingLine) {
152        this.accountingLine = accountingLine;
153    }
154
155    /**
156     * Renders the override field and its associated override needed field
157     * @see org.kuali.ole.sys.document.web.renderers.Renderer#render(javax.servlet.jsp.PageContext, javax.servlet.jsp.tagext.Tag)
158     */
159    public void render(PageContext pageContext, Tag parentTag) throws JspException {
160        if ((readOnly && getField().getPropertyValue().equals("Yes")) || overrideNeededValue.equals("Yes")) {
161            renderOverrideAsNonHidden(pageContext, parentTag);
162            if (!readOnly) {
163                renderOverridePresent(pageContext, parentTag);
164            }
165        } else {
166        }
167   }
168    
169    /**
170     * @return the HTML for a line break
171     */
172    protected String buildLineBreak() {
173        return "<br />";
174    }
175    
176    /**
177     * @return the HTML for a non-breaking space
178     */
179    protected String buildNonBreakingSpace() {
180        return "&nbsp;";
181    }
182
183    /**
184     * @return builds the opening of the span tag to go around the label
185     */
186    protected String buildLabelSpanOpening() {
187        return "<span style=\"font-weight: normal\">";
188    }
189    
190    /**
191     * @return builds the closing of the span tag to go around the label
192     */
193    protected String buildLabelSpanClosing() {
194        return "</span>";
195    }
196    
197    /**
198     * Renders the override field as non-hidden (probably a checkbox) 
199     * @param pageContext the page context to render to
200     * @param parentTag the tag requesting all this rendering
201     * @throws JspException thrown if rendering fails
202     */
203    protected void renderOverrideAsNonHidden(PageContext pageContext, Tag parentTag) throws JspException {
204        JspWriter out = pageContext.getOut();
205        try {
206            out.write(buildLineBreak());
207            openNoWrapSpan(pageContext, parentTag);
208            out.write(buildLabelSpanOpening());
209            overrideLabelRenderer.setLabel(getField().getFieldLabel());
210            overrideLabelRenderer.setRequired(true);
211            overrideLabelRenderer.setReadOnly(false);
212            overrideLabelRenderer.setLabelFor(getField().getPropertyPrefix()+"."+getField().getPropertyName());
213            overrideLabelRenderer.render(pageContext, parentTag);
214            out.write(buildLabelSpanClosing());
215            out.write(buildNonBreakingSpace());
216            overrideFieldRenderer =  readOnly ? new ReadOnlyRenderer() : SpringContext.getBean(AccountingLineRenderingService.class).getFieldRendererForField(getField(), accountingLine);
217            if (overrideFieldRenderer instanceof ReadOnlyRenderer) {
218                ((ReadOnlyRenderer)overrideFieldRenderer).setShouldRenderInquiry(false);
219                out.write(": "); // add a colon to make it prettier
220                // populate the field again
221                getField().setPropertyValue(storedFieldValue);
222            }
223            overrideFieldRenderer.setField(getField());
224            overrideFieldRenderer.setArbitrarilyHighTabIndex(getQuickfinderTabIndex());
225            overrideFieldRenderer.render(pageContext, parentTag);
226            closeNoWrapSpan(pageContext, parentTag);
227        }
228        catch (IOException ioe) {
229            throw new JspException("Difficulty rendering override field", ioe);
230        }
231    }
232    
233    /**
234     * Renders the override field as a hidden field
235     * @param pageContext the page context to render to
236     * @param parentTag the tag requesting all this rendering
237     * @throws JspException thrown if rendering fails
238     */
239    protected void renderOverrideAsHidden(PageContext pageContext, Tag parentTag) throws JspException {
240        overrideHiddenTag.setPageContext(pageContext);
241        overrideHiddenTag.setParent(parentTag);
242        overrideHiddenTag.setProperty(getField().getPropertyPrefix()+"."+getField().getPropertyName());
243        if (!readOnly && overrideNeededValue.equals("No")) {
244            overrideHiddenTag.setValue("No");
245        } else {
246            overrideHiddenTag.setValue(getField().getPropertyValue());
247        }
248        overrideHiddenTag.doStartTag();
249        overrideHiddenTag.doEndTag();
250    }
251    
252    /**
253     * Renders the override field as a hidden field
254     * @param pageContext the page context to render to
255     * @param parentTag the tag requesting all this rendering
256     * @throws JspException thrown if rendering fails
257     */
258    protected void renderOverridePresent(PageContext pageContext, Tag parentTag) throws JspException {
259        overridePresentTag.setPageContext(pageContext);
260        overridePresentTag.setParent(parentTag);
261        overridePresentTag.setProperty(getField().getPropertyPrefix()+"."+getField().getPropertyName()+".present");
262        overridePresentTag.setValue("I'm here yo!");
263        overridePresentTag.doStartTag();
264        overridePresentTag.doEndTag();
265    }
266    
267    /**
268     * Renders the overrideNeeded field (which is always hidden)
269     * @param pageContext the page context to render to
270     * @param parentTag the tag requesting all this rendering
271     * @throws JspException thrown if rendering fails
272     */
273    protected void renderOverrideNeededField(PageContext pageContext, Tag parentTag) throws JspException {
274        overrideNeededTag.setPageContext(pageContext);
275        overrideNeededTag.setParent(parentTag);
276        overrideNeededTag.setProperty(overrideNeededProperty);
277        overrideNeededTag.setValue(overrideNeededValue);
278        overrideNeededTag.doStartTag();
279        overrideNeededTag.doEndTag();
280    }
281}