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.PageContext;
022import javax.servlet.jsp.tagext.Tag;
023
024import org.apache.commons.lang.StringUtils;
025import org.kuali.ole.sys.context.SpringContext;
026import org.kuali.rice.core.api.config.property.ConfigurationService;
027import org.kuali.rice.kns.web.ui.Field;
028import org.kuali.rice.krad.util.KRADConstants;
029
030/**
031 * Base class for all renderers which render fields
032 */
033public abstract class FieldRendererBase implements FieldRenderer {
034    private Field field;
035    private String dynamicNameLabel;
036    private int arbitrarilyHighTabIndex = -1;
037    private String onBlur;
038    private boolean showError;
039    private String accessibleTitle;
040    private static String riceImageBase;
041
042    /**
043     * Sets the field to render
044     * @see org.kuali.ole.sys.document.web.renderers.FieldRenderer#setField(org.kuali.rice.kns.web.ui.Field)
045     * 
046     * KRAD Conversion - Setting the field - No Use of data dictionary
047     */
048    public void setField(Field field) {
049        this.field = field;
050    }
051    
052    /**
053     * Returns the field to render
054     * @return the field to render
055     * 
056     * KRAD Conversion - Getting the field - No Use of data dictionary
057     */
058    public Field getField() {
059        return this.field;
060    }
061    
062    /**
063     * @return the name this field should have on the form
064     */
065    protected String getFieldName() {
066        if (!StringUtils.isBlank(field.getPropertyPrefix())) return field.getPropertyPrefix()+"."+field.getPropertyName();
067        return field.getPropertyName();
068    }
069
070    /**
071     * Clears the field
072     * @see org.kuali.ole.sys.document.web.renderers.Renderer#clear()
073     */
074    public void clear() {
075        this.field = null;
076        this.arbitrarilyHighTabIndex = -1;
077        this.onBlur = null;
078    }
079    
080    /**
081     * Returns an accessible title for the field being rendered
082     * @return an accessible title for the field to render
083     */
084    protected String getAccessibleTitle() {
085        return accessibleTitle;
086    }
087    
088    /**
089     * Sets the accessible title of the current field 
090     * @param accessibleTitle the given the accessible title 
091     */
092    public void setAccessibleTitle(String accessibleTitle) {
093        this.accessibleTitle = accessibleTitle;
094    }
095    
096    /**
097     * Renders a quick finder for the field if one is warranted
098     * @param pageContext the page context to render to
099     * @param parentTag the parent tag requesting all of this rendering
100     * @param businessObjectToRender the business object that will be rendered
101     * @throws JspException thrown if something's off
102     */
103    protected void renderQuickFinderIfNecessary(PageContext pageContext, Tag parentTag) throws JspException {
104        if (!StringUtils.isBlank(getField().getQuickFinderClassNameImpl()) && renderQuickfinder()) {
105            QuickFinderRenderer renderer = new QuickFinderRenderer();
106            renderer.setField(getField());
107            renderer.setTabIndex(getQuickfinderTabIndex());
108            renderer.setAccessibleTitle(getField().getFieldLabel());
109            renderer.render(pageContext, parentTag);
110            renderer.clear();
111        }
112    }
113    
114    /**
115     * Writes the onblur call for the wrapped field
116     * @return a value for onblur=
117     */
118    protected String buildOnBlur() {
119        if (onBlur == null) {
120            StringBuilder onblur = new StringBuilder();
121            if (!StringUtils.isBlank(getField().getWebOnBlurHandler())) {
122                onblur.append(getField().getWebOnBlurHandler());
123                onblur.append("( this.name");
124                if (!StringUtils.isBlank(getDynamicNameLabel())) {
125                    onblur.append(", '");
126                    onblur.append(getDynamicNameLabel());
127                    onblur.append("'");
128                }
129                onblur.append(" );");
130            }
131            onBlur = onblur.toString();
132        }
133        return onBlur;
134    }
135    
136    /**
137     * Overrides the onBlur setting for this renderer
138     * @param onBlur the onBlur value to set and return from buildOnBlur
139     */
140    public void overrideOnBlur(String onBlur) {
141        this.onBlur = onBlur;
142    }
143    
144    /**
145     * @return the dynamic name label field
146     */
147    protected String getDynamicNameLabel() {
148        return dynamicNameLabel;
149    }
150    
151    /** 
152     * @see org.kuali.ole.sys.document.web.renderers.FieldRenderer#setDynamicNameLabel(java.lang.String)
153     */
154    public void setDynamicNameLabel(String dynamicNameLabel) {
155        this.dynamicNameLabel = dynamicNameLabel;
156    }
157
158    /**
159     * @see org.kuali.ole.sys.document.web.renderers.FieldRenderer#setArbitrarilyHighTabIndex(int)
160     */
161    public void setArbitrarilyHighTabIndex(int tabIndex) {
162        this.arbitrarilyHighTabIndex = tabIndex;   
163    }
164    
165    /**
166     * @return the tab index the quick finder should use - which, by default, is the arbitrarily high tab index
167     */
168    protected int getQuickfinderTabIndex() {
169        return arbitrarilyHighTabIndex;
170    }
171
172    /**
173     * @see org.kuali.ole.sys.document.web.renderers.FieldRenderer#closeNoWrapSpan()
174     */
175    public void closeNoWrapSpan(PageContext pageContext, Tag parentTag) throws JspException {
176        try {
177            pageContext.getOut().write("</span>");
178        }
179        catch (IOException ioe) {
180            throw new JspException("Could not render closing of no-wrap span", ioe);
181        }
182    }
183
184    /**
185     * @see org.kuali.ole.sys.document.web.renderers.FieldRenderer#openNoWrapSpan()
186     */
187    public void openNoWrapSpan(PageContext pageContext, Tag parentTag) throws JspException {
188        try {
189            pageContext.getOut().write("<span class=\"nowrap\">");
190        }
191        catch (IOException ioe) {
192            throw new JspException("Could not render opening of no-wrap span", ioe);
193        }
194    }
195
196    /**
197     * Gets the showError attribute. 
198     * @return Returns the showError.
199     */
200    public boolean isShowError() {
201        return showError;
202    }
203
204    /**
205     * Sets the showError attribute value.
206     * @param showError The showError to set.
207     */
208    public void setShowError(boolean showError) {
209        this.showError = showError;
210    }
211    
212    /**
213     * Renders the error icon
214     * @param pageContext the page context to render to
215     * @throws IOException thrown if the pageContext cannot be written to
216     */
217    protected void renderErrorIcon(PageContext pageContext) throws JspException {
218        try {
219            pageContext.getOut().write(getErrorIconImageTag());
220        }
221        catch (IOException ioe) {
222            throw new JspException("Could not render error icon", ioe);
223        }
224    }
225    
226    /**
227     * @return the tag for the error icon
228     */
229    protected String getErrorIconImageTag() {
230        return "<img src=\""+getErrorIconImageSrc()+"\" alt=\"error\" />";
231    }
232    
233    /**
234     * @return the source of the error icon
235     */
236    private String getErrorIconImageSrc() {
237        return getRiceImageBase()+"errormark.gif";
238    }
239    
240    /**
241     * @return the source of rice images
242     */
243    private String getRiceImageBase() {
244        if (riceImageBase == null) {
245            riceImageBase = SpringContext.getBean(ConfigurationService.class).getPropertyValueAsString(KRADConstants.EXTERNALIZABLE_IMAGES_URL_KEY);
246        }
247        return riceImageBase;
248    }
249}