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