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.lookup;
017
018 import java.beans.PropertyDescriptor;
019 import java.util.ArrayList;
020 import java.util.Collection;
021 import java.util.HashMap;
022 import java.util.List;
023 import java.util.Map;
024
025 import org.apache.commons.beanutils.PropertyUtils;
026 import org.apache.commons.lang.StringUtils;
027 import org.apache.commons.logging.Log;
028 import org.apache.commons.logging.LogFactory;
029 import org.kuali.kfs.integration.ld.SegmentedBusinessObject;
030 import org.kuali.kfs.module.ld.businessobject.LedgerBalance;
031 import org.kuali.kfs.module.ld.businessobject.inquiry.AbstractLaborInquirableImpl;
032 import org.kuali.kfs.module.ld.businessobject.inquiry.LedgerBalanceForExpenseTransferInquirableImpl;
033 import org.kuali.kfs.module.ld.businessobject.inquiry.PositionDataDetailsInquirableImpl;
034 import org.kuali.kfs.sys.KFSConstants;
035 import org.kuali.kfs.sys.KFSPropertyConstants;
036 import org.kuali.kfs.sys.context.SpringContext;
037 import org.kuali.rice.kim.bo.Person;
038 import org.kuali.rice.kns.authorization.BusinessObjectRestrictions;
039 import org.kuali.rice.kns.bo.BusinessObject;
040 import org.kuali.rice.kns.bo.PersistableBusinessObject;
041 import org.kuali.rice.kns.datadictionary.mask.Mask;
042 import org.kuali.rice.kns.lookup.HtmlData;
043 import org.kuali.rice.kns.lookup.HtmlData.AnchorHtmlData;
044 import org.kuali.rice.kns.util.GlobalVariables;
045 import org.kuali.rice.kns.util.ObjectUtils;
046 import org.kuali.rice.kns.web.comparator.CellComparatorHelper;
047 import org.kuali.rice.kns.web.format.BooleanFormatter;
048 import org.kuali.rice.kns.web.format.Formatter;
049 import org.kuali.rice.kns.web.struts.form.LookupForm;
050 import org.kuali.rice.kns.web.ui.Column;
051 import org.kuali.rice.kns.web.ui.ResultRow;
052
053 /**
054 * Service implementation of LedgerBalanceForExpenseTransferLookupableHelperService.
055 */
056
057 public abstract class LedgerBalanceForExpenseTransferLookupableHelperServiceImpl extends LedgerBalanceLookupableHelperServiceImpl {
058 private static final Log LOG = LogFactory.getLog(LedgerBalanceForExpenseTransferLookupableHelperServiceImpl.class);
059
060 /**
061 * @see org.kuali.rice.kns.lookup.Lookupable#getInquiryUrl(org.kuali.rice.kns.bo.BusinessObject, java.lang.String)
062 */
063 @Override
064 public HtmlData getInquiryUrl(BusinessObject bo, String propertyName) {
065 if (KFSPropertyConstants.POSITION_NUMBER.equals(propertyName)) {
066 LedgerBalance balance = (LedgerBalance) bo;
067 AbstractLaborInquirableImpl positionDataDetailsInquirable = new PositionDataDetailsInquirableImpl();
068
069 Map<String, String> fieldValues = new HashMap<String, String>();
070 fieldValues.put(propertyName, balance.getPositionNumber());
071
072 BusinessObject positionData = positionDataDetailsInquirable.getBusinessObject(fieldValues);
073
074 return positionData == null ? new AnchorHtmlData() : positionDataDetailsInquirable.getInquiryUrl(positionData, propertyName);
075 }
076 return (new LedgerBalanceForExpenseTransferInquirableImpl()).getInquiryUrl(bo, propertyName);
077 }
078
079 /**
080 * @see org.kuali.kfs.module.ld.businessobject.lookup.LedgerBalanceLookupableHelperServiceImpl#getSearchResults(java.util.Map)
081 */
082 @Override
083 public List<? extends BusinessObject> getSearchResults(Map<String, String> fieldValues) {
084 return null;
085 }
086
087 /**
088 * This method performs the lookup and returns a collection of lookup items
089 *
090 * @param lookupForm
091 * @param lookupable
092 * @param resultTable
093 * @param bounded
094 * @return
095 */
096 public Collection performLookup(LookupForm lookupForm, Collection resultTable, boolean bounded) {
097 Collection<BusinessObject> displayList;
098
099 // call search method to get results
100 if (bounded) {
101 displayList = (Collection<BusinessObject>) getSearchResults(lookupForm.getFieldsForLookup());
102 }
103 else {
104 displayList = (Collection<BusinessObject>) getSearchResultsUnbounded(lookupForm.getFieldsForLookup());
105 }
106
107 List pkNames = getBusinessObjectMetaDataService().listPrimaryKeyFieldNames(getBusinessObjectClass());
108 List returnKeys = getReturnKeys();
109 Person user = GlobalVariables.getUserSession().getPerson();
110 // iterate through result list and wrap rows with return url and action urls
111 for (BusinessObject element : displayList) {
112 LOG.debug("Doing lookup for " + element.getClass());
113 BusinessObjectRestrictions businessObjectRestrictions = getBusinessObjectAuthorizationService().getLookupResultRestrictions(element, user);
114 String returnUrl =
115 getReturnUrl(element, lookupForm, returnKeys, businessObjectRestrictions).constructCompleteHtmlTag();
116
117 if (element instanceof PersistableBusinessObject) {
118 if (element instanceof SegmentedBusinessObject) {
119 LOG.debug("segmented property names " + ((SegmentedBusinessObject) element).getSegmentedPropertyNames());
120
121 Collection<Column> columns = getColumns(element, businessObjectRestrictions);
122 ResultRow row = new ResultRow((List<Column>) columns, returnUrl, getActionUrls(element, pkNames, businessObjectRestrictions));
123
124 for (String propertyName : ((SegmentedBusinessObject) element).getSegmentedPropertyNames()) {
125 columns.add(setupResultsColumn(element, propertyName, businessObjectRestrictions));
126 }
127
128 row.setObjectId(((PersistableBusinessObject) element).getObjectId());
129 resultTable.add(row);
130 }
131 else {
132 Collection<Column> columns = getColumns(element, businessObjectRestrictions);
133
134 ResultRow row = new ResultRow((List<Column>) columns, returnUrl, getActionUrls(element, pkNames, businessObjectRestrictions));
135 row.setObjectId(((PersistableBusinessObject) element).getObjectId());
136 resultTable.add(row);
137 }
138 }
139 }
140
141 return displayList;
142 }
143
144 /**
145 * @param element
146 * @param attributeName
147 * @return Column
148 */
149 protected Column setupResultsColumn(BusinessObject element, String attributeName, BusinessObjectRestrictions businessObjectRestrictions) {
150 Column col = new Column();
151
152 col.setPropertyName(attributeName);
153
154 String columnTitle = getDataDictionaryService().getAttributeLabel(getBusinessObjectClass(), attributeName);
155 if (StringUtils.isBlank(columnTitle)) {
156 columnTitle = getDataDictionaryService().getCollectionLabel(getBusinessObjectClass(), attributeName);
157 }
158 col.setColumnTitle(columnTitle);
159 col.setMaxLength(getDataDictionaryService().getAttributeMaxLength(getBusinessObjectClass(), attributeName));
160
161 Class formatterClass = getDataDictionaryService().getAttributeFormatter(getBusinessObjectClass(), attributeName);
162 Formatter formatter = null;
163 if (formatterClass != null) {
164 try {
165 formatter = (Formatter) formatterClass.newInstance();
166 col.setFormatter(formatter);
167 }
168 catch (InstantiationException e) {
169 LOG.error("Unable to get new instance of formatter class: " + formatterClass.getName());
170 throw new RuntimeException("Unable to get new instance of formatter class: " + formatterClass.getName());
171 }
172 catch (IllegalAccessException e) {
173 LOG.error("Unable to get new instance of formatter class: " + formatterClass.getName());
174 throw new RuntimeException("Unable to get new instance of formatter class: " + formatterClass.getName());
175 }
176 }
177
178 // pick off result column from result list, do formatting
179 String propValue = KFSConstants.EMPTY_STRING;
180 Object prop = ObjectUtils.getPropertyValue(element, attributeName);
181
182 // set comparator and formatter based on property type
183 Class propClass = null;
184 try {
185 PropertyDescriptor propDescriptor = PropertyUtils.getPropertyDescriptor(element, col.getPropertyName());
186 if (propDescriptor != null) {
187 propClass = propDescriptor.getPropertyType();
188 }
189 }
190 catch (Exception e) {
191 throw new RuntimeException("Cannot access PropertyType for property " + "'" + col.getPropertyName() + "' " + " on an instance of '" + element.getClass().getName() + "'.", e);
192 }
193
194 // formatters
195 if (prop != null) {
196 // for Booleans, always use BooleanFormatter
197 if (prop instanceof Boolean) {
198 formatter = new BooleanFormatter();
199 }
200
201 if (formatter != null) {
202 propValue = (String) formatter.format(prop);
203 }
204 else {
205 propValue = prop.toString();
206 }
207 }
208
209 // comparator
210 col.setComparator(CellComparatorHelper.getAppropriateComparatorForPropertyClass(propClass));
211 col.setValueComparator(CellComparatorHelper.getAppropriateValueComparatorForPropertyClass(propClass));
212
213 propValue = super.maskValueIfNecessary(element.getClass(), col.getPropertyName(), propValue, businessObjectRestrictions);
214 col.setPropertyValue(propValue);
215
216
217 if (StringUtils.isNotBlank(propValue)) {
218 col.setColumnAnchor(getInquiryUrl(element, col.getPropertyName()));
219 }
220 return col;
221 }
222
223
224 /**
225 * Constructs the list of columns for the search results. All properties for the column objects come from the DataDictionary.
226 *
227 * @param bo
228 * @return Collection<Column>
229 */
230 protected Collection<Column> getColumns(BusinessObject bo, BusinessObjectRestrictions businessObjectRestrictions) {
231 Collection<Column> columns = new ArrayList<Column>();
232
233 for (String attributeName : getBusinessObjectDictionaryService().getLookupResultFieldNames(getBusinessObjectClass())) {
234 columns.add(setupResultsColumn(bo, attributeName, businessObjectRestrictions));
235 }
236 return columns;
237 }
238 }
239