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.commons.lang.StringUtils; 026import org.kuali.ole.sys.OLEConstants; 027import org.kuali.ole.sys.context.SpringContext; 028import org.kuali.rice.core.api.config.property.ConfigurationService; 029import org.kuali.rice.core.api.util.KeyValue; 030import org.kuali.rice.kns.lookup.HtmlData.AnchorHtmlData; 031import org.kuali.rice.kns.web.ui.Field; 032 033/** 034 * Renderer which displays a read only field 035 */ 036public class ReadOnlyRenderer extends FieldRendererBase { 037 private boolean shouldRenderInquiry = true; 038 039 /** 040 * @see org.kuali.ole.sys.document.web.renderers.Renderer#render(javax.servlet.jsp.PageContext, javax.servlet.jsp.tagext.Tag) 041 */ 042 @Override 043 public void render(PageContext pageContext, Tag parentTag) throws JspException { 044 JspWriter out = pageContext.getOut(); 045 046 try { 047 String value = discoverRenderValue(); 048 out.write(buildBeginSpan()); 049 050 if (!StringUtils.isEmpty(value)) { 051 if (shouldRenderInquiryLink()) { 052 out.write(buildBeginInquiryLink()); 053 } 054 out.write(value); 055 if (shouldRenderInquiryLink()) { 056 out.write(buildEndInquiryLink()); 057 } 058 } else { 059 out.write(buildNonBreakingSpace()); 060 } 061 062 out.write(buildEndSpan()); 063 } 064 catch (IOException ioe) { 065 throw new JspException("Difficulty rendering read only field", ioe); 066 } 067 } 068 069 /** 070 * Clears the persisting tag. 071 * @see org.kuali.ole.sys.document.web.renderers.FieldRendererBase#clear() 072 */ 073 @Override 074 public void clear() { 075 super.clear(); 076 } 077 078 /** 079 * Generates the HTML for the opening span tag to wrap the displayed value 080 * @param propertyPrefix the property path from the form the business object being rendered 081 * @return the HTML for the opening span 082 */ 083 protected String buildBeginSpan() { 084 StringBuilder beginSpan = new StringBuilder(); 085 beginSpan.append("<span id=\""); 086 beginSpan.append(getFieldName()); 087 beginSpan.append(".div\">"); 088 return beginSpan.toString(); 089 } 090 091 /** 092 * Generates the HTML for the closing span tag to wrap the displayed value 093 * @return the HTML for the closing span 094 */ 095 protected String buildEndSpan() { 096 return "</span>"; 097 } 098 099 /** 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}