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 " ";
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 }