View Javadoc
1   /*
2    * Copyright 2008 The Kuali Foundation
3    * 
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    * http://www.opensource.org/licenses/ecl2.php
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.ole.sys.document.web.renderers;
17  
18  import java.io.IOException;
19  
20  import javax.servlet.jsp.JspException;
21  import javax.servlet.jsp.JspWriter;
22  import javax.servlet.jsp.PageContext;
23  import javax.servlet.jsp.tagext.Tag;
24  
25  import org.apache.commons.lang.StringUtils;
26  import org.kuali.ole.sys.OLEConstants;
27  import org.kuali.ole.sys.context.SpringContext;
28  import org.kuali.rice.core.api.config.property.ConfigurationService;
29  import org.kuali.rice.core.api.util.KeyValue;
30  import org.kuali.rice.kns.lookup.HtmlData.AnchorHtmlData;
31  import org.kuali.rice.kns.web.ui.Field;
32  
33  /**
34   * Renderer which displays a read only field
35   */
36  public class ReadOnlyRenderer extends FieldRendererBase {
37      private boolean shouldRenderInquiry = true;
38      
39      /**
40       * @see org.kuali.ole.sys.document.web.renderers.Renderer#render(javax.servlet.jsp.PageContext, javax.servlet.jsp.tagext.Tag)
41       */
42      @Override
43      public void render(PageContext pageContext, Tag parentTag) throws JspException {
44          JspWriter out = pageContext.getOut();
45  
46          try {
47              String value = discoverRenderValue();
48              out.write(buildBeginSpan());
49              
50              if (!StringUtils.isEmpty(value)) {
51                  if (shouldRenderInquiryLink()) {
52                      out.write(buildBeginInquiryLink());
53                  }                
54                  out.write(value);                
55                  if (shouldRenderInquiryLink()) {
56                      out.write(buildEndInquiryLink());
57                  }                                
58              } else {
59                  out.write(buildNonBreakingSpace());
60              }
61              
62              out.write(buildEndSpan());
63          }
64          catch (IOException ioe) {
65              throw new JspException("Difficulty rendering read only field", ioe);
66          }
67      }
68  
69      /**
70       * Clears the persisting tag.
71       * @see org.kuali.ole.sys.document.web.renderers.FieldRendererBase#clear()
72       */
73      @Override
74      public void clear() {
75          super.clear();
76      }
77  
78      /**
79       * Generates the HTML for the opening span tag to wrap the displayed value
80       * @param propertyPrefix the property path from the form the business object being rendered
81       * @return the HTML for the opening span 
82       */
83      protected String buildBeginSpan() {
84          StringBuilder beginSpan = new StringBuilder();        
85          beginSpan.append("<span id=\"");
86          beginSpan.append(getFieldName());
87          beginSpan.append(".div\">");        
88          return beginSpan.toString();
89      }
90      
91      /**
92       * Generates the HTML for the closing span tag to wrap the displayed value
93       * @return the HTML for the closing span
94       */
95      protected String buildEndSpan() {
96          return "</span>";
97      }
98      
99      /**
100      * Builds the opening anchor tag to make the displayed read only value open up an inquiry screen
101      * @return the HTML for the opening inquiry anchor tag
102      */
103     protected String buildBeginInquiryLink() {
104         StringBuilder beginInquiryLink = new StringBuilder();
105         
106         if (getField().getInquiryURL() instanceof AnchorHtmlData) {
107             AnchorHtmlData htmlData = (AnchorHtmlData) getField().getInquiryURL();
108 
109             if(htmlData.getHref().startsWith("http")) {
110                 beginInquiryLink.append("<a href=\"");
111             }
112             else {
113             beginInquiryLink.append("<a href=\"");
114                 beginInquiryLink.append(SpringContext.getBean(ConfigurationService.class).getPropertyValueAsString(OLEConstants.APPLICATION_URL_KEY));
115             beginInquiryLink.append("/kr/");
116             }
117 
118             beginInquiryLink.append(htmlData.getHref());
119             beginInquiryLink.append("\" title=\"");
120             beginInquiryLink.append(htmlData.getTitle());
121             beginInquiryLink.append("\" target=\"blank\">");
122             
123         }
124         
125         return beginInquiryLink.toString();
126     }
127     
128     /**
129      * Builds the closing anchor tag for the inquiry link
130      * @return the HTML for the closing inquiry anchor tag
131      */
132     protected String buildEndInquiryLink() {
133         if (getField().getInquiryURL() instanceof AnchorHtmlData) {
134             return "</a>";
135         }
136         return "";
137     }
138     
139     /**
140      * Determines if this read only field should attempt to display the inquiry link around the rendered value
141      * @return true if the inquiry link should be rendered, false otherwise
142      */
143     protected boolean shouldRenderInquiryLink() {
144         return getField().getInquiryURL() != null && !StringUtils.isBlank(((AnchorHtmlData)getField().getInquiryURL()).getHref()) && isInquirableValue(getField().getPropertyValue())  && shouldRenderInquiry;
145     }
146     
147     /**
148      * Determines if the given property value is worthy of having an inquiry for it
149      * @param propertyValue the value of the property to potentially render an inquiry for
150      * @return true if the value is inquirable; false otherwise
151      */
152     protected boolean isInquirableValue(String propertyValue) {
153         return !StringUtils.isBlank(propertyValue) && !propertyValue.matches("^-*$");
154     }
155     
156     /**
157      * Sets the shouldRenderInquiry attribute value.
158      * @param shouldRenderInquiry The shouldRenderInquiry to set.
159      */
160     public void setShouldRenderInquiry(boolean shouldRenderInquiry) {
161         this.shouldRenderInquiry = shouldRenderInquiry;
162     }
163 
164     /**
165      * Dropdowns are typically fields with codes, which may be close to meaningless, with more explanative labels.  Therefore,
166      * fields which are drop downs should display the label instead
167      * @return the label for the chosen key on the field if possible; otherwise, an empty String
168      */
169     protected String getValueForDropDown() {
170         for (Object keyLabelPairAsObject : getField().getFieldValidValues()) {
171             final KeyValue keyLabelPair = (KeyValue)keyLabelPairAsObject;
172             if (getField().getPropertyValue().equalsIgnoreCase(keyLabelPair.getKey().toString())) {
173                 return keyLabelPair.getValue();
174             }
175         }
176         return null;
177     }
178     
179     /**
180      * An algorithm to discover the actual read only value to render.  If this is a drop down, it finds the renderable value for the drop down;
181      * if the value is unavailable, it searches for the property in unconverted values
182      * @return the value to display
183      * 
184      * KRAD Conversion: Discovering fields values
185      */
186     protected String discoverRenderValue() {
187         String value = getField().getPropertyValue();
188         if (getField().getFieldType().equals(Field.DROPDOWN) && !StringUtils.isEmpty(value)) {
189             value = getValueForDropDown();
190         }
191         
192         return value;
193     }
194     
195     /**
196      * @return the HTML for a non-breaking space, so the box isn't all empty
197      */
198     protected String buildNonBreakingSpace() {
199         return "&nbsp;";
200     }
201 
202     /**
203      * Nope, no quick finder here
204      * @see org.kuali.ole.sys.document.web.renderers.FieldRenderer#renderQuickfinder()
205      */
206     @Override
207     public boolean renderQuickfinder() {
208         return false;
209     }
210 
211     /**
212      * @see org.kuali.ole.sys.document.web.renderers.FieldRendererBase#closeNoWrapSpan(javax.servlet.jsp.PageContext, javax.servlet.jsp.tagext.Tag)
213      */
214     @Override
215     public void closeNoWrapSpan(PageContext pageContext, Tag parentTag) throws JspException {
216         // do nothing - read onlys don't need "no wrap"
217     }
218 
219     /**
220      * @see org.kuali.ole.sys.document.web.renderers.FieldRendererBase#openNoWrapSpan(javax.servlet.jsp.PageContext, javax.servlet.jsp.tagext.Tag)
221      */
222     @Override
223     public void openNoWrapSpan(PageContext pageContext, Tag parentTag) throws JspException {
224         // do nothing - read onlys don't need "no wrap"
225     }
226     
227 }