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.module.ld.businessobject.inquiry; 017 018 import java.sql.Date; 019 import java.util.ArrayList; 020 import java.util.HashMap; 021 import java.util.Iterator; 022 import java.util.List; 023 import java.util.Map; 024 import java.util.Properties; 025 026 import org.kuali.kfs.gl.Constant; 027 import org.kuali.kfs.module.ld.LaborConstants; 028 import org.kuali.kfs.sys.KFSConstants; 029 import org.kuali.kfs.sys.KFSPropertyConstants; 030 import org.kuali.kfs.sys.ObjectUtil; 031 import org.kuali.kfs.sys.businessobject.inquiry.KfsInquirableImpl; 032 import org.kuali.kfs.sys.context.SpringContext; 033 import org.kuali.rice.kns.bo.BusinessObject; 034 import org.kuali.rice.kns.lookup.HtmlData; 035 import org.kuali.rice.kns.lookup.LookupUtils; 036 import org.kuali.rice.kns.lookup.HtmlData.AnchorHtmlData; 037 import org.kuali.rice.kns.service.BusinessObjectDictionaryService; 038 import org.kuali.rice.kns.service.DateTimeService; 039 import org.kuali.rice.kns.service.PersistenceStructureService; 040 import org.kuali.rice.kns.util.ObjectUtils; 041 import org.kuali.rice.kns.util.UrlFactory; 042 043 /** 044 * This class is the template class for the customized inqurable implementations used to generate balance inquiry screens. 045 */ 046 public abstract class AbstractLaborInquirableImpl extends KfsInquirableImpl { 047 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(AbstractLaborInquirableImpl.class); 048 049 /** 050 * Helper method to build an inquiry url for a result field. 051 * 052 * @param businessObject the business object instance to build the urls for 053 * @param attributeName the attribute name which links to an inquirable 054 * @return String url to inquiry 055 */ 056 public HtmlData getInquiryUrl(BusinessObject businessObject, String attributeName) { 057 BusinessObjectDictionaryService businessDictionary = SpringContext.getBean(BusinessObjectDictionaryService.class); 058 PersistenceStructureService persistenceStructureService = SpringContext.getBean(PersistenceStructureService.class); 059 060 HtmlData inquiryHref = new AnchorHtmlData(Constant.EMPTY_STRING, Constant.EMPTY_STRING); 061 String baseUrl = KFSConstants.INQUIRY_ACTION; 062 Properties parameters = new Properties(); 063 parameters.put(KFSConstants.DISPATCH_REQUEST_PARAMETER, KFSConstants.START_METHOD); 064 065 Object attributeValue = null; 066 Class inquiryBusinessObjectClass = null; 067 String attributeRefName = Constant.EMPTY_STRING; 068 boolean isPkReference = false; 069 070 Map userDefinedAttributeMap = getUserDefinedAttributeMap(); 071 boolean isUserDefinedAttribute = userDefinedAttributeMap == null ? false : userDefinedAttributeMap.containsKey(attributeName); 072 073 // determine the type of the given attribute: user-defined, regular, nested-referenced or primitive reference 074 if (isUserDefinedAttribute) { 075 attributeName = getAttributeName(attributeName); 076 inquiryBusinessObjectClass = getInquiryBusinessObjectClass(attributeName); 077 isPkReference = true; 078 } 079 else if (attributeName.equals(businessDictionary.getTitleAttribute(businessObject.getClass()))) { 080 inquiryBusinessObjectClass = businessObject.getClass(); 081 isPkReference = true; 082 } 083 else if (ObjectUtils.isNestedAttribute(attributeName)) { 084 return inquiryHref; 085 } 086 else { 087 Map primitiveReference = LookupUtils.getPrimitiveReference(businessObject, attributeName); 088 if (primitiveReference != null && !primitiveReference.isEmpty()) { 089 attributeRefName = (String) primitiveReference.keySet().iterator().next(); 090 inquiryBusinessObjectClass = (Class) primitiveReference.get(attributeRefName); 091 } 092 attributeValue = ObjectUtils.getPropertyValue(businessObject, attributeName); 093 attributeValue = (attributeValue == null) ? "" : attributeValue.toString(); 094 } 095 096 // process the business object class if the attribute name is not user-defined 097 if (!isUserDefinedAttribute) { 098 if (isExclusiveFieldToBeALink(attributeName, attributeValue)) { 099 return inquiryHref; 100 } 101 102 if (inquiryBusinessObjectClass == null || businessDictionary.isInquirable(inquiryBusinessObjectClass) == null || !businessDictionary.isInquirable(inquiryBusinessObjectClass).booleanValue()) { 103 return inquiryHref; 104 } 105 } 106 parameters.put(KFSConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE, inquiryBusinessObjectClass.getName()); 107 108 List keys = new ArrayList(); 109 if (isUserDefinedAttribute) { 110 baseUrl = getBaseUrl(); 111 keys = buildUserDefinedAttributeKeyList(); 112 113 parameters.put(KFSConstants.RETURN_LOCATION_PARAMETER, Constant.RETURN_LOCATION_VALUE); 114 parameters.put(KFSConstants.GL_BALANCE_INQUIRY_FLAG, "true"); 115 parameters.put(KFSConstants.DISPATCH_REQUEST_PARAMETER, KFSConstants.SEARCH_METHOD); 116 parameters.put(KFSConstants.DOC_FORM_KEY, "88888888"); 117 } 118 else if (persistenceStructureService.isPersistable(inquiryBusinessObjectClass)) { 119 keys = persistenceStructureService.listPrimaryKeyFieldNames(inquiryBusinessObjectClass); 120 } 121 122 // build key value url parameters used to retrieve the business object 123 Map<String,String> inquiryFields = new HashMap<String,String>(); 124 if (keys != null) { 125 StringBuffer title = new StringBuffer(Constant.EMPTY_STRING); 126 for (Iterator keyIterator = keys.iterator(); keyIterator.hasNext();) { 127 String keyName = (String) keyIterator.next(); 128 129 // convert the key names based on their formats and types 130 String keyConversion = keyName; 131 if (ObjectUtils.isNestedAttribute(attributeName)) { 132 if (isUserDefinedAttribute) { 133 keyConversion = keyName; 134 } 135 else { 136 keyConversion = ObjectUtils.getNestedAttributePrefix(attributeName) + "." + keyName; 137 } 138 } 139 else { 140 if (isPkReference) { 141 keyConversion = keyName; 142 } 143 else { 144 keyConversion = persistenceStructureService.getForeignKeyFieldName(businessObject.getClass(), attributeRefName, keyName); 145 } 146 } 147 148 Object keyValue = ObjectUtils.getPropertyValue(businessObject, keyConversion); 149 if(ObjectUtil.getSimpleTypeName(businessObject, keyConversion).equals(Date.class.getSimpleName())) { 150 Date date = (Date)ObjectUtil.valueOf(Date.class.getSimpleName(), keyValue.toString()); 151 152 DateTimeService dateTimeService = SpringContext.getBean(DateTimeService.class); 153 keyValue = dateTimeService.toDateString(new java.util.Date(date.getTime())); 154 } 155 156 keyValue = (keyValue == null) ? Constant.EMPTY_STRING : keyValue.toString(); 157 158 // convert the key value and name into the given ones 159 Object tempKeyValue = this.getKeyValue(keyName, keyValue); 160 keyValue = tempKeyValue == null ? keyValue : tempKeyValue; 161 162 String tempKeyName = this.getKeyName(keyName); 163 keyName = tempKeyName == null ? keyName : tempKeyName; 164 165 // add the key-value pair into the parameter map 166 if (keyName != null){ 167 parameters.put(keyName, keyValue); 168 inquiryFields.put(keyName, keyValue.toString()); 169 } 170 } 171 } 172 173 // add more customized parameters into the current parameter map 174 if (isUserDefinedAttribute) { 175 addMoreParameters(parameters, attributeName); 176 } 177 return getHyperLink(inquiryBusinessObjectClass, inquiryFields, UrlFactory.parameterizeUrl(baseUrl, parameters)); 178 } 179 180 /** 181 * This method builds the inquiry url for user-defined attribute 182 * 183 * @return key list 184 */ 185 protected abstract List buildUserDefinedAttributeKeyList(); 186 187 /** 188 * This method defines the user-defined attribute map 189 * 190 * @return the user-defined attribute map 191 */ 192 protected abstract Map getUserDefinedAttributeMap(); 193 194 /** 195 * This method finds the matching attribute name of given one 196 * 197 * @param attributeName the given attribute name 198 * @return the attribute name from the given one 199 */ 200 protected abstract String getAttributeName(String attributeName); 201 202 /** 203 * This method finds the matching the key value of the given one 204 * 205 * @param keyName the given key name 206 * @param keyValue the given key value 207 * @return the key value from the given key value 208 */ 209 protected abstract Object getKeyValue(String keyName, Object keyValue); 210 211 /** 212 * This method finds the matching the key name of the given one 213 * 214 * @param keyName the given key name 215 * @return the key value from the given key name 216 */ 217 protected abstract String getKeyName(String keyName); 218 219 /** 220 * This method defines the lookupable implementation attribute name 221 * 222 * @return the lookupable implementation attribute name 223 */ 224 protected abstract String getLookupableImplAttributeName(); 225 226 /** 227 * This method defines the base inquiry url 228 * 229 * @return the base inquiry url 230 */ 231 protected abstract String getBaseUrl(); 232 233 /** 234 * This method gets the class name of the inquiry business object for a given attribute. 235 * 236 * @return the class name of the inquiry business object for a given attribute 237 */ 238 protected abstract Class getInquiryBusinessObjectClass(String attributeName); 239 240 /** 241 * This method adds more parameters into the curren parameter map 242 * 243 * @param parameter the current parameter map 244 */ 245 protected void addMoreParameters(Properties parameter, String attributeName) { 246 return; 247 } 248 249 /** 250 * This method determines whether the input name-value pair is exclusive from the processing 251 * 252 * @param keyName the name of the name-value pair 253 * @param keyValue the value of the name-value pair 254 * @return true if the input key is in the exclusive list; otherwise, false 255 */ 256 protected boolean isExclusiveField(Object keyName, Object keyValue) { 257 258 if (keyName != null && keyValue != null) { 259 260 if (keyName.equals(KFSPropertyConstants.SUB_ACCOUNT_NUMBER) && keyValue.equals(Constant.CONSOLIDATED_SUB_ACCOUNT_NUMBER)) { 261 return true; 262 } 263 else if (keyName.equals(KFSPropertyConstants.FINANCIAL_SUB_OBJECT_CODE) && keyValue.equals(Constant.CONSOLIDATED_SUB_OBJECT_CODE)) { 264 return true; 265 } 266 else if (keyName.equals(KFSPropertyConstants.FINANCIAL_OBJECT_TYPE_CODE) && keyValue.equals(Constant.CONSOLIDATED_OBJECT_TYPE_CODE)) { 267 return true; 268 } 269 } 270 return false; 271 } 272 273 /** 274 * This method determines whether the input name-value pair is exclusive to be a link 275 * 276 * @param keyName the name of the name-value pair 277 * @param keyValue the value of the name-value pair 278 * @return true if the input key is in the exclusive list; otherwise, false 279 */ 280 protected boolean isExclusiveFieldToBeALink(Object keyName, Object keyValue) { 281 282 if (keyName != null && keyValue != null) { 283 284 if (isExclusiveField(keyName, keyValue)) { 285 return true; 286 } 287 else if (keyName.equals(KFSPropertyConstants.SUB_ACCOUNT_NUMBER) && keyValue.equals(KFSConstants.getDashSubAccountNumber())) { 288 return true; 289 } 290 else if (keyName.equals(KFSPropertyConstants.FINANCIAL_SUB_OBJECT_CODE) && keyValue.equals(KFSConstants.getDashFinancialSubObjectCode())) { 291 return true; 292 } 293 else if (keyName.equals(KFSPropertyConstants.PROJECT_CODE) && keyValue.equals(KFSConstants.getDashProjectCode())) { 294 return true; 295 } 296 else if (keyName.equals(KFSPropertyConstants.POSITION_NUMBER) && keyValue.equals(LaborConstants.getDashPositionNumber())) { 297 return true; 298 } 299 else if (keyName.equals(KFSPropertyConstants.FINANCIAL_BALANCE_TYPE_CODE) && keyValue.equals(LaborConstants.BalanceInquiries.BALANCE_TYPE_AC_AND_A21)) { 300 return true; 301 } 302 } 303 return false; 304 } 305 }