001/**
002 * Copyright 2005-2016 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.rice.kew.rule.bo;
017
018import org.apache.commons.lang.StringUtils;
019import org.kuali.rice.core.api.uif.RemotableAttributeError;
020import org.kuali.rice.core.api.util.ConcreteKeyValue;
021import org.kuali.rice.core.api.util.KeyValue;
022import org.kuali.rice.core.api.util.RiceKeyConstants;
023import org.kuali.rice.core.web.format.BooleanFormatter;
024import org.kuali.rice.core.web.format.CollectionFormatter;
025import org.kuali.rice.core.web.format.DateFormatter;
026import org.kuali.rice.core.web.format.Formatter;
027import org.kuali.rice.kew.api.KewApiConstants;
028import org.kuali.rice.kew.api.KewApiServiceLocator;
029import org.kuali.rice.kew.api.rule.RuleTemplate;
030import org.kuali.rice.kew.api.rule.RuleTemplateAttribute;
031import org.kuali.rice.kew.lookupable.MyColumns;
032import org.kuali.rice.kew.rule.RuleBaseValues;
033import org.kuali.rice.kew.rule.RuleDelegationBo;
034import org.kuali.rice.kew.rule.RuleExtensionBo;
035import org.kuali.rice.kew.rule.WorkflowRuleAttributeRows;
036import org.kuali.rice.kew.rule.service.RuleDelegationService;
037import org.kuali.rice.kew.rule.service.RuleTemplateService;
038import org.kuali.rice.kew.service.KEWServiceLocator;
039import org.kuali.rice.kim.api.KimConstants;
040import org.kuali.rice.kim.api.group.Group;
041import org.kuali.rice.kim.api.group.GroupService;
042import org.kuali.rice.kim.api.identity.Person;
043import org.kuali.rice.kim.api.identity.principal.Principal;
044import org.kuali.rice.kim.api.services.KimApiServiceLocator;
045import org.kuali.rice.kns.document.authorization.BusinessObjectRestrictions;
046import org.kuali.rice.kns.lookup.HtmlData;
047import org.kuali.rice.kns.lookup.KualiLookupableHelperServiceImpl;
048import org.kuali.rice.kns.web.comparator.CellComparatorHelper;
049import org.kuali.rice.kns.web.struts.form.LookupForm;
050import org.kuali.rice.kns.web.ui.Column;
051import org.kuali.rice.kns.web.ui.Field;
052import org.kuali.rice.kns.web.ui.ResultRow;
053import org.kuali.rice.kns.web.ui.Row;
054import org.kuali.rice.krad.bo.BusinessObject;
055import org.kuali.rice.krad.bo.PersistableBusinessObject;
056import org.kuali.rice.krad.exception.ValidationException;
057import org.kuali.rice.krad.util.GlobalVariables;
058import org.kuali.rice.krad.util.KRADConstants;
059import org.kuali.rice.krad.util.ObjectUtils;
060
061import java.sql.Date;
062import java.util.ArrayList;
063import java.util.Collection;
064import java.util.HashMap;
065import java.util.Iterator;
066import java.util.List;
067import java.util.Map;
068
069/**
070 * This is a description of what this class does - jjhanso don't forget to fill this in.
071 *
072 * @author Kuali Rice Team (rice.collab@kuali.org)
073 *
074 */
075public class RuleDelegationLookupableHelperServiceImpl extends KualiLookupableHelperServiceImpl {
076    private List<Row> rows = new ArrayList<Row>();
077    //private List<Column> columns = establishColumns();
078    //private Long previousRuleTemplateId;
079    private static final String PARENT_RESPONSIBILITY_ID_PROPERTY_NAME = "responsibilityId";
080    private static final String PARENT_RULE_ID_PROPERTY_NAME = "ruleResponsibility.ruleBaseValuesId";
081    private static final String RULE_TEMPLATE_PROPERTY_NAME = "delegationRule.ruleTemplate.name";
082    private static final String RULE_ID_PROPERTY_NAME = "delegationRule.id";
083    private static final String ACTIVE_IND_PROPERTY_NAME = "delegationRule.active";
084    private static final String DELEGATION_PROPERTY_NAME = "delegationType";
085    private static final String GROUP_REVIEWER_PROPERTY_NAME = "groupReviewer";
086    private static final String GROUP_REVIEWER_NAME_PROPERTY_NAME = "groupReviewerName";
087    private static final String GROUP_REVIEWER_NAMESPACE_PROPERTY_NAME = "groupReviewerNamespace";
088    private static final String PERSON_REVIEWER_PROPERTY_NAME = "personReviewer";
089    private static final String PERSON_REVIEWER_TYPE_PROPERTY_NAME = "personReviewerType";
090    private static final String DOC_TYP_NAME_PROPERTY_NAME = "delegationRule.documentType.name";
091    private static final String RULE_DESC_PROPERTY_NAME = "delegationRule.description";
092
093    private static final String BACK_LOCATION = "backLocation";
094    private static final String DOC_FORM_KEY = "docFormKey";
095    private static final String INVALID_WORKGROUP_ERROR = "The Group Reviewer Namespace and Name combination is not valid";
096    private static final String INVALID_PERSON_ERROR = "The Person Reviewer is not valid";
097
098    @Override
099        public List<Row> getRows() {
100        List<Row> superRows = super.getRows();
101        List<Row> returnRows = new ArrayList<Row>();
102        returnRows.addAll(superRows);
103        returnRows.addAll(rows);
104        return returnRows;
105    }
106
107    @Override
108    public boolean checkForAdditionalFields(Map<String, String> fieldValues) {
109        String ruleTemplateNameParam = fieldValues.get(RULE_TEMPLATE_PROPERTY_NAME);
110
111        if (StringUtils.isNotBlank(ruleTemplateNameParam)) {
112            rows = new ArrayList<Row>();
113            RuleTemplate ruleTemplate = KewApiServiceLocator.getRuleService().getRuleTemplateByName(ruleTemplateNameParam);
114
115            for (RuleTemplateAttribute ruleTemplateAttribute : ruleTemplate.getActiveRuleTemplateAttributes()) {
116                if (!RuleAttribute.isWorkflowAttribute(ruleTemplateAttribute.getRuleAttribute().getType())) {
117                    continue;
118                }
119                // run through the attributes fields once to populate field values we have to do this
120                // to allow rows dependent on another row value to populate correctly in the loop below
121                WorkflowRuleAttributeRows workflowRuleAttributeRows =
122                        KEWServiceLocator.getWorkflowRuleAttributeMediator().getSearchRows(fieldValues, ruleTemplateAttribute);
123                for (Row row : workflowRuleAttributeRows.getRows()) {
124                    List<Field> fields = new ArrayList<Field>();
125                    for (Iterator<Field> iterator2 = row.getFields().iterator(); iterator2.hasNext(); ) {
126                        Field field = (Field) iterator2.next();
127                        if (fieldValues.get(field.getPropertyName()) != null) {
128                            field.setPropertyValue(fieldValues.get(field.getPropertyName()));
129                        }
130                        fields.add(field);
131                        fieldValues.put(field.getPropertyName(), field.getPropertyValue());
132                    }
133                }
134                // now run through a second time with our shiny new field values
135                // ...by the way, just trying to preserve behavior from Rice 1.0.x here...generally speaking, this stuff is crazy!!!
136                workflowRuleAttributeRows =
137                        KEWServiceLocator.getWorkflowRuleAttributeMediator().getSearchRows(fieldValues, ruleTemplateAttribute);
138                for (Row row : workflowRuleAttributeRows.getRows()) {
139                    List<Field> fields = new ArrayList<Field>();
140                    for (Iterator<Field> iterator2 = row.getFields().iterator(); iterator2.hasNext(); ) {
141                        Field field = iterator2.next();
142                        if (fieldValues.get(field.getPropertyName()) != null) {
143                            field.setPropertyValue(fieldValues.get(field.getPropertyName()));
144                        }
145                        fields.add(field);
146                        fieldValues.put(field.getPropertyName(), field.getPropertyValue());
147                    }
148                    row.setFields(fields);
149                    rows.add(row);
150
151                }
152            }
153            return true;
154        }
155        rows.clear();
156        return false;
157    }
158
159    @Override
160    public List<? extends BusinessObject> getSearchResults(Map<String, String> fieldValues) {
161        String parentRuleBaseValueId = fieldValues.get(PARENT_RULE_ID_PROPERTY_NAME);
162        String parentResponsibilityId = fieldValues.get(PARENT_RESPONSIBILITY_ID_PROPERTY_NAME);
163        String docTypeNameParam = fieldValues.get(DOC_TYP_NAME_PROPERTY_NAME);
164        String ruleTemplateIdParam = null;
165        String ruleTemplateNameParam = fieldValues.get(RULE_TEMPLATE_PROPERTY_NAME);
166        String groupIdParam = fieldValues.get(GROUP_REVIEWER_PROPERTY_NAME);
167        String groupNameParam = fieldValues.get(GROUP_REVIEWER_NAME_PROPERTY_NAME);
168        String groupNamespaceParam = fieldValues.get(GROUP_REVIEWER_NAMESPACE_PROPERTY_NAME);
169        String networkIdParam = fieldValues.get(PERSON_REVIEWER_PROPERTY_NAME);
170        String userDirectiveParam = fieldValues.get(PERSON_REVIEWER_TYPE_PROPERTY_NAME);
171        String activeParam = fieldValues.get(ACTIVE_IND_PROPERTY_NAME);
172        String delegationParam = fieldValues.get(DELEGATION_PROPERTY_NAME);
173        String ruleIdParam = fieldValues.get(RULE_ID_PROPERTY_NAME);
174        String ruleDescription = fieldValues.get(RULE_DESC_PROPERTY_NAME);
175
176        String docTypeSearchName = null;
177        String workflowId = null;
178        String workgroupId = null;
179        String ruleTemplateId = null;
180        Boolean isActive = null;
181        String ruleId = null;
182
183        if (ruleIdParam != null && !"".equals(ruleIdParam.trim())) {
184            ruleId = ruleIdParam.trim();
185        }
186
187        if (!activeParam.equals("")) {
188            if (activeParam.equals("Y")) {
189                isActive = Boolean.TRUE;
190            } else {
191                isActive = Boolean.FALSE;
192            }
193        }
194
195        if (docTypeNameParam != null && !"".equals(docTypeNameParam.trim())) {
196            docTypeSearchName = docTypeNameParam.replace('*', '%');
197            docTypeSearchName = "%" + docTypeSearchName.trim() + "%";
198        }
199
200        if (StringUtils.isNotBlank(networkIdParam)) {
201            Principal principal = KimApiServiceLocator.getIdentityService().getPrincipalByPrincipalName(networkIdParam);
202                if (principal != null) {
203                        workflowId = principal.getPrincipalId();
204                }
205        }
206
207        if (StringUtils.isNotBlank(groupIdParam) || StringUtils.isNotBlank(groupNameParam)) {
208            Group group = null;
209            if (groupIdParam != null && !"".equals(groupIdParam)) {
210                group = getGroupService().getGroup(groupIdParam.trim());
211            } else {
212                if (groupNamespaceParam == null) {
213                    groupNamespaceParam = KimConstants.KIM_GROUP_DEFAULT_NAMESPACE_CODE;
214                }
215                group = getGroupService().getGroupByNamespaceCodeAndName(groupNamespaceParam, groupNameParam.trim());
216                if (group == null) {
217                    GlobalVariables.getMessageMap().putError(GROUP_REVIEWER_NAMESPACE_PROPERTY_NAME, RiceKeyConstants.ERROR_CUSTOM, INVALID_WORKGROUP_ERROR);
218                } else {
219                    workgroupId = group.getId();
220                }
221            }
222        }
223
224        Map<String, String> attributes = null;
225        MyColumns myColumns = new MyColumns();
226        if (StringUtils.isNotBlank(ruleTemplateNameParam) || StringUtils.isNotBlank(ruleTemplateIdParam) && !"null".equals(ruleTemplateIdParam)) {
227            RuleTemplate ruleTemplate = null;
228            if (StringUtils.isNotBlank(ruleTemplateIdParam)) {
229                ruleTemplate = KewApiServiceLocator.getRuleService().getRuleTemplate(ruleTemplateIdParam);
230            } else {
231                ruleTemplate = KewApiServiceLocator.getRuleService().getRuleTemplateByName(ruleTemplateNameParam.trim());
232                ruleTemplateId = ruleTemplate.getId();
233            }
234
235            if (ruleTemplate == null) {
236                rows.clear();
237                LOG.info("Returning empty result set for Delegation Rule Lookup because a RuleTemplate Name or ID was provided, but no valid RuleTemplates were retrieved by the service.");
238                return new ArrayList<RuleDelegationBo>();
239            }
240
241            attributes = new HashMap<String, String>();
242
243            for (RuleTemplateAttribute ruleTemplateAttribute : ruleTemplate.getActiveRuleTemplateAttributes()) {
244                if (!RuleAttribute.isWorkflowAttribute(ruleTemplateAttribute.getRuleAttribute().getType())) {
245                    continue;
246                }
247                WorkflowRuleAttributeRows workflowRuleAttributeRows =
248                        KEWServiceLocator.getWorkflowRuleAttributeMediator().getSearchRows(fieldValues, ruleTemplateAttribute, false);
249
250                for (RemotableAttributeError error : workflowRuleAttributeRows.getValidationErrors()) {
251                    GlobalVariables.getMessageMap().putError(error.getAttributeName(), RiceKeyConstants.ERROR_CUSTOM, error.getMessage());
252                }
253
254                for (Row row : workflowRuleAttributeRows.getRows()) {
255                    for (Field field : row.getFields()) {
256                        if (fieldValues.get(field.getPropertyName()) != null) {
257                            String attributeParam = fieldValues.get(field.getPropertyName());
258                            if (!attributeParam.equals("")) {
259                                attributes.put(field.getPropertyName(), attributeParam.trim());
260                            }
261                        }
262                        if (field.getFieldType().equals(Field.TEXT) || field.getFieldType().equals(Field.DROPDOWN) || field.getFieldType().equals(Field.DROPDOWN_REFRESH) || field.getFieldType().equals(Field.RADIO)) {
263                            myColumns.getColumns().add(new ConcreteKeyValue(field.getPropertyName(), ruleTemplateAttribute.getId()));
264                        }
265                    }
266                }
267            }
268        }
269
270        if (StringUtils.isNotBlank(ruleDescription)) {
271            ruleDescription = ruleDescription.replace('*', '%');
272            ruleDescription = "%" + ruleDescription.trim() + "%";
273        }
274
275        if (GlobalVariables.getMessageMap().hasErrors()) {
276            throw new ValidationException("errors in search criteria");
277        }
278
279        // TODO: replace this with new API find method ??
280        Iterator<RuleDelegationBo> rules = getRuleDelegationService().search(parentRuleBaseValueId, parentResponsibilityId, docTypeSearchName, ruleId, ruleTemplateId, ruleDescription, workgroupId, workflowId, delegationParam, isActive, attributes, userDirectiveParam).iterator();
281        List<RuleDelegationBo> displayList = new ArrayList<RuleDelegationBo>();
282
283        while (rules.hasNext()) {
284            RuleDelegationBo ruleDelegation = rules.next();
285            RuleBaseValues record = ruleDelegation.getDelegationRule();
286
287            if (StringUtils.isBlank(record.getDescription())) {
288                record.setDescription(KewApiConstants.HTML_NON_BREAKING_SPACE);
289            }
290
291            if (ruleTemplateNameParam != null && !ruleTemplateNameParam.trim().equals("") || ruleTemplateIdParam != null && !"".equals(ruleTemplateIdParam) && !"null".equals(ruleTemplateIdParam)) {
292                MyColumns myNewColumns = new MyColumns();
293                for (Object element : myColumns.getColumns()) {
294                    KeyValue pair = (KeyValue) element;
295                    final KeyValue newPair;
296                    List<RuleExtensionBo> ruleExts = record.getRuleExtensions();
297                    for (RuleExtensionBo ruleExt : ruleExts) {
298                        if(ruleExt.getExtensionValuesMap().containsKey(pair.getKey().toString())){
299                            ruleTemplateIdParam = ruleExt.getRuleTemplateAttributeId();
300                        }
301                    }
302                    if (record.getRuleExtensionValue(ruleTemplateIdParam, pair.getKey().toString()) != null) {
303                        newPair = new ConcreteKeyValue(pair.getKey(), record.getRuleExtensionValue(ruleTemplateIdParam, pair.getKey().toString()).getValue());
304                    } else {
305                        newPair = new ConcreteKeyValue(pair.getKey(), KewApiConstants.HTML_NON_BREAKING_SPACE);
306                    }
307                    myNewColumns.getColumns().add(newPair);
308                    record.getFieldValues().put(newPair.getKey(), newPair.getValue());
309                }
310                record.setMyColumns(myNewColumns);
311            }
312
313            StringBuilder returnUrl = new StringBuilder("<a href=\"");
314            returnUrl.append(fieldValues.get(BACK_LOCATION)).append("?methodToCall=refresh&docFormKey=").append(fieldValues.get(DOC_FORM_KEY)).append("&");
315
316            returnUrl.append(RULE_ID_PROPERTY_NAME);
317            returnUrl.append("=").append(record.getId()).append("\">return value</a>");
318            record.setReturnUrl(returnUrl.toString());
319
320            String destinationUrl = "<a href=\"Rule.do?methodToCall=report&currentRuleId=" + record.getId() + "\">report</a>";
321
322            record.setDestinationUrl(destinationUrl);
323
324            displayList.add(ruleDelegation);
325        }
326        return displayList;
327
328    }
329
330
331
332    private GroupService getGroupService() {
333       return KimApiServiceLocator.getGroupService();
334    }
335
336    private RuleTemplateService getRuleTemplateService() {
337        return (RuleTemplateService) KEWServiceLocator.getService(KEWServiceLocator.RULE_TEMPLATE_SERVICE);
338    }
339    private RuleDelegationService getRuleDelegationService() {
340        return (RuleDelegationService) KEWServiceLocator.getService(KEWServiceLocator.RULE_DELEGATION_SERVICE);
341    }
342
343    @Override
344    public void validateSearchParameters(Map<String, String> fieldValues) {
345        super.validateSearchParameters(fieldValues);
346
347        // make sure that if we have either groupName or Namespace, that both are filled in
348        String groupName = (String)fieldValues.get(GROUP_REVIEWER_NAME_PROPERTY_NAME);
349        String groupNamespace = (String)fieldValues.get(GROUP_REVIEWER_NAMESPACE_PROPERTY_NAME);
350        String principalName = (String)fieldValues.get(PERSON_REVIEWER_PROPERTY_NAME);
351
352        if (StringUtils.isEmpty(groupName) && !StringUtils.isEmpty(groupNamespace)) {
353            String attributeLabel = getDataDictionaryService().getAttributeLabel(getBusinessObjectClass(), GROUP_REVIEWER_NAME_PROPERTY_NAME);
354            GlobalVariables.getMessageMap().putError(GROUP_REVIEWER_NAME_PROPERTY_NAME, RiceKeyConstants.ERROR_REQUIRED, attributeLabel);
355        }
356
357        if  (!StringUtils.isEmpty(groupName) && StringUtils.isEmpty(groupNamespace)) {
358            String attributeLabel = getDataDictionaryService().getAttributeLabel(getBusinessObjectClass(), GROUP_REVIEWER_NAMESPACE_PROPERTY_NAME);
359            GlobalVariables.getMessageMap().putError(GROUP_REVIEWER_NAMESPACE_PROPERTY_NAME, RiceKeyConstants.ERROR_REQUIRED, attributeLabel);
360        }
361
362        if  (!StringUtils.isEmpty(groupName) && !StringUtils.isEmpty(groupNamespace)) {
363            Group group = KimApiServiceLocator.getGroupService().getGroupByNamespaceCodeAndName(groupNamespace,
364                    groupName);
365            if (group == null) {
366                GlobalVariables.getMessageMap().putError(GROUP_REVIEWER_NAME_PROPERTY_NAME, RiceKeyConstants.ERROR_CUSTOM, INVALID_WORKGROUP_ERROR);
367            }
368        }
369
370        if  (!StringUtils.isEmpty(principalName)) {
371            Person person = KimApiServiceLocator.getPersonService().getPersonByPrincipalName(principalName);
372            if (person == null) {
373                GlobalVariables.getMessageMap().putError(PERSON_REVIEWER_PROPERTY_NAME, RiceKeyConstants.ERROR_CUSTOM, INVALID_PERSON_ERROR);
374            }
375        }
376        if (!GlobalVariables.getMessageMap().hasNoErrors()) {
377            throw new ValidationException("errors in search criteria");
378        }
379    }
380
381    @Override
382    public Collection performLookup(LookupForm lookupForm,
383            Collection resultTable, boolean bounded) {
384        // TODO jjhanso - THIS METHOD NEEDS JAVADOCS
385        //return super.performLookup(lookupForm, resultTable, bounded);
386        setBackLocation((String) lookupForm.getFieldsForLookup().get(KRADConstants.BACK_LOCATION));
387        setDocFormKey((String) lookupForm.getFieldsForLookup().get(KRADConstants.DOC_FORM_KEY));
388        Collection displayList;
389
390        // call search method to get results
391        if (bounded) {
392            displayList = getSearchResults(lookupForm.getFieldsForLookup());
393        }
394        else {
395            displayList = getSearchResultsUnbounded(lookupForm.getFieldsForLookup());
396        }
397
398        HashMap<String,Class> propertyTypes = new HashMap<String, Class>();
399
400        boolean hasReturnableRow = false;
401
402        List returnKeys = getReturnKeys();
403        List pkNames = getBusinessObjectMetaDataService().listPrimaryKeyFieldNames(getBusinessObjectClass());
404        Person user = GlobalVariables.getUserSession().getPerson();
405
406        // iterate through result list and wrap rows with return url and action urls
407        for (Iterator iter = displayList.iterator(); iter.hasNext();) {
408            BusinessObject element = (BusinessObject) iter.next();
409            if(element instanceof PersistableBusinessObject){
410                lookupForm.setLookupObjectId(((PersistableBusinessObject)element).getObjectId());
411            }
412
413            BusinessObjectRestrictions businessObjectRestrictions = getBusinessObjectAuthorizationService().getLookupResultRestrictions(element, user);
414
415            HtmlData returnUrl = getReturnUrl(element, lookupForm, returnKeys, businessObjectRestrictions);
416
417            String actionUrls = getActionUrls(element, pkNames, businessObjectRestrictions);
418            //Fix for JIRA - KFSMI-2417
419            if("".equals(actionUrls)){
420                actionUrls = ACTION_URLS_EMPTY;
421            }
422
423            List<Column> columns = getColumns();
424            for (Object element2 : columns) {
425
426                Column col = (Column) element2;
427                String curPropName = col.getPropertyName();
428                Formatter formatter = col.getFormatter();
429
430                // pick off result column from result list, do formatting
431                String propValue = KRADConstants.EMPTY_STRING;
432                Object prop = null;
433                boolean skipPropTypeCheck = false;
434                //try to get value elsewhere
435                if (element instanceof RuleDelegationBo) {
436                    prop = ((RuleDelegationBo)element).getDelegationRule().getFieldValues().get(curPropName);
437                    skipPropTypeCheck = true;
438                }
439                if (prop == null) {
440                    prop = ObjectUtils.getPropertyValue(element, curPropName);
441                }
442
443                // set comparator and formatter based on property type
444                Class propClass = propertyTypes.get(curPropName);
445                if ( propClass == null && !skipPropTypeCheck) {
446                    try {
447                        propClass = ObjectUtils.getPropertyType( element, curPropName, getPersistenceStructureService() );
448                        propertyTypes.put( curPropName, propClass );
449                    } catch (Exception e) {
450                        throw new RuntimeException("Cannot access PropertyType for property " + "'" + curPropName + "' " + " on an instance of '" + element.getClass().getName() + "'.", e);
451                    }
452                }
453
454                // formatters
455                if (prop != null) {
456                    // for Booleans, always use BooleanFormatter
457                    if (prop instanceof Boolean) {
458                        formatter = new BooleanFormatter();
459                    }
460
461                    // for Dates, always use DateFormatter
462                    if (prop instanceof Date) {
463                        formatter = new DateFormatter();
464                    }
465
466                    // for collection, use the list formatter if a formatter hasn't been defined yet
467                    if (prop instanceof Collection && formatter == null) {
468                    formatter = new CollectionFormatter();
469                    }
470
471                    if (formatter != null) {
472                        propValue = (String) formatter.format(prop);
473                    }
474                    else {
475                        propValue = prop.toString();
476                    }
477                }
478
479                // comparator
480                col.setComparator(CellComparatorHelper.getAppropriateComparatorForPropertyClass(propClass));
481                col.setValueComparator(CellComparatorHelper.getAppropriateValueComparatorForPropertyClass(propClass));
482
483                propValue = maskValueIfNecessary(element.getClass(), curPropName, propValue, businessObjectRestrictions);
484
485                col.setPropertyValue(propValue);
486
487                if (StringUtils.isNotBlank(propValue)) {
488                    col.setColumnAnchor(getInquiryUrl(element, curPropName));
489
490                }
491            }
492
493            ResultRow row = new ResultRow(columns, returnUrl.constructCompleteHtmlTag(), actionUrls);
494            row.setRowId(returnUrl.getName());
495            row.setReturnUrlHtmlData(returnUrl);
496            // because of concerns of the BO being cached in session on the ResultRow,
497            // let's only attach it when needed (currently in the case of export)
498            if (getBusinessObjectDictionaryService().isExportable(getBusinessObjectClass())) {
499                row.setBusinessObject(element);
500            }
501            if(element instanceof PersistableBusinessObject){
502                row.setObjectId((((PersistableBusinessObject)element).getObjectId()));
503            }
504
505
506            boolean rowReturnable = isResultReturnable(element);
507            row.setRowReturnable(rowReturnable);
508            if (rowReturnable) {
509                hasReturnableRow = true;
510            }
511            resultTable.add(row);
512        }
513
514        lookupForm.setHasReturnableRow(hasReturnableRow);
515
516        return displayList;
517    }
518
519    @Override
520    public List<Column> getColumns() {
521        List<Column> columns = super.getColumns();
522        for (Row row : rows) {
523            for (Field field : row.getFields()) {
524                Column newColumn = new Column();
525                newColumn.setColumnTitle(field.getFieldLabel());
526                newColumn.setMaxLength(field.getMaxLength());
527                newColumn.setPropertyName(field.getPropertyName());
528                columns.add(newColumn);
529            }
530        }
531        return columns;
532    }
533
534    @Override
535    public List<HtmlData> getCustomActionUrls(BusinessObject businessObject,
536            List pkNames) {
537        RuleDelegationBo ruleDelegation = (RuleDelegationBo)businessObject;
538        List<HtmlData> htmlDataList = new ArrayList<HtmlData>();
539        if (StringUtils.isNotBlank(ruleDelegation.getDelegationRule().getRuleTemplateName()) && StringUtils.isNotBlank(getMaintenanceDocumentTypeName())) {
540                if (allowsMaintenanceEditAction(businessObject)) {
541                        htmlDataList.add(getUrlData(businessObject, KRADConstants.MAINTENANCE_EDIT_METHOD_TO_CALL, pkNames));
542                }
543            if (allowsMaintenanceNewOrCopyAction()) {
544                htmlDataList.add(getUrlData(businessObject, KRADConstants.MAINTENANCE_COPY_METHOD_TO_CALL, pkNames));
545            }
546        }
547            
548        return htmlDataList;
549    }
550
551
552
553}