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 }