001    /**
002     * Copyright 2005-2013 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.rice.kns.lookup;
017    
018    import org.apache.commons.lang.StringUtils;
019    import org.kuali.rice.core.api.util.RiceKeyConstants;
020    import org.kuali.rice.kim.api.identity.Person;
021    import org.kuali.rice.kim.api.identity.principal.Principal;
022    import org.kuali.rice.kim.api.services.KimApiServiceLocator;
023    import org.kuali.rice.kim.impl.KIMPropertyConstants;
024    import org.kuali.rice.kns.util.FieldUtils;
025    import org.kuali.rice.kns.web.ui.Field;
026    import org.kuali.rice.kns.web.ui.Row;
027    import org.kuali.rice.krad.bo.BusinessObject;
028    import org.kuali.rice.krad.document.authorization.PessimisticLock;
029    import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
030    import org.kuali.rice.krad.service.PessimisticLockService;
031    import org.kuali.rice.krad.util.BeanPropertyComparator;
032    import org.kuali.rice.krad.util.GlobalVariables;
033    import org.kuali.rice.krad.util.KRADConstants;
034    import org.kuali.rice.krad.util.KRADPropertyConstants;
035    import org.kuali.rice.krad.util.ObjectUtils;
036    
037    import java.util.ArrayList;
038    import java.util.Collections;
039    import java.util.Iterator;
040    import java.util.List;
041    import java.util.Map;
042    
043    /**
044     * This class is the lookup helper for {@link org.kuali.rice.krad.document.authorization.PessimisticLock} objects
045     *
046     * @author Kuali Rice Team (rice.collab@kuali.org)
047     *
048     */
049    public class PessimisticLockLookupableHelperServiceImpl extends AbstractLookupableHelperServiceImpl {
050        private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PessimisticLockLookupableHelperServiceImpl.class);
051    
052        private static final long serialVersionUID = -5839142187907211804L;
053        private static final String OWNER_PRINCIPAL_ID_PROPERTY_NAME = "ownedByPrincipalIdentifier";
054        private static final String OWNER_PRINCIPAL_NAME_PROPERTY_NAME = "ownedByUser.principalName";
055    
056        private List<Row> localRows;
057    
058        /**
059         * Hides the applicable links when the PessimisticLock is not owned by the current user
060         *
061         * @see org.kuali.rice.krad.lookup.LookupableHelperService#getCustomActionUrls(org.kuali.rice.krad.bo.BusinessObject, java.util.List, java.util.List pkNames)
062         */
063        @Override
064        public List<HtmlData> getCustomActionUrls(BusinessObject businessObject, List pkNames) {
065            PessimisticLock lock = (PessimisticLock)businessObject;
066            if ( (lock.isOwnedByUser(GlobalVariables.getUserSession().getPerson())) || (KRADServiceLocatorWeb
067                    .getPessimisticLockService().isPessimisticLockAdminUser(GlobalVariables.getUserSession().getPerson())) ) {
068                List<HtmlData> anchorHtmlDataList = new ArrayList<HtmlData>();
069                anchorHtmlDataList.add(getUrlData(businessObject, KRADConstants.DELETE_METHOD, pkNames));
070                return anchorHtmlDataList;
071            } else {
072                return super.getEmptyActionUrls();
073            }
074        }
075    
076        /**
077         * This overridden method checks whether the user is an admin user according to {@link PessimisticLockService#isPessimisticLockAdminUser(Person)} and if the user is not an admin user the user field is set to Read Only and the lookup field
078         *
079         * @see org.kuali.rice.krad.lookup.AbstractLookupableHelperServiceImpl#getRows()
080         */
081        @Override
082        public List<Row> getRows() {
083            Person currentUser = GlobalVariables.getUserSession().getPerson();
084            if (KRADServiceLocatorWeb.getPessimisticLockService().isPessimisticLockAdminUser(currentUser)) {
085                return super.getRows();
086            } else {
087                if ( (ObjectUtils.isNull(localRows)) || localRows.isEmpty() ) {
088                    List<Field> fieldList = new ArrayList<Field>();
089                    int numColumns = -1;
090                    // hide a field and forcibly set a field
091                    for (Iterator<Row> iterator = super.getRows().iterator(); iterator.hasNext();) {
092                        Row row = (Row) iterator.next();
093                        if (numColumns == -1) {
094                            numColumns = row.getFields().size();
095                        }
096                        for (Iterator<Field> iterator2 = row.getFields().iterator(); iterator2.hasNext();) {
097                            Field field = (Field) iterator2.next();
098                            if (!(KRADPropertyConstants.OWNED_BY_USER + "." + KIMPropertyConstants.Person.PRINCIPAL_NAME).equals(field.getPropertyName()) &&
099                                            !Field.BLANK_SPACE.equals(field.getFieldType())) {
100                                fieldList.add(field);
101                            }
102                        }
103                    }
104                    // Since the removed field is the first one in the list, use FieldUtils to re-wrap the remaining fields accordingly.
105                    localRows = FieldUtils.wrapFields(fieldList, numColumns);
106                }
107                return localRows;
108            }
109        }
110    
111        /**
112         * This method implementation is used to search for objects
113         *
114         * @see org.kuali.rice.krad.lookup.AbstractLookupableHelperServiceImpl#getSearchResults(java.util.Map)
115         */
116        @Override
117        public List<? extends BusinessObject> getSearchResults(Map<String, String> fieldValues) {
118            // remove hidden fields
119            org.kuali.rice.kns.lookup.LookupUtils.removeHiddenCriteriaFields(getBusinessObjectClass(), fieldValues);
120            // force criteria if not admin user
121            Person currentUser = GlobalVariables.getUserSession().getPerson();
122            if (!KRADServiceLocatorWeb.getPessimisticLockService().isPessimisticLockAdminUser(currentUser)) {
123                fieldValues.put(KRADPropertyConstants.OWNED_BY_PRINCIPAL_ID,GlobalVariables.getUserSession().getPerson().getPrincipalId());
124            }
125    
126            //set owner's principal id and remove owner principal name field 
127            String principalName = fieldValues.get(OWNER_PRINCIPAL_NAME_PROPERTY_NAME);
128            if (!StringUtils.isEmpty(principalName)) {
129                Principal principal = KimApiServiceLocator.getIdentityService().getPrincipalByPrincipalName(principalName);
130                if (principal != null) { 
131                    fieldValues.put(OWNER_PRINCIPAL_ID_PROPERTY_NAME, principal.getPrincipalId());
132                }
133                fieldValues.remove(OWNER_PRINCIPAL_NAME_PROPERTY_NAME);
134            }
135            
136            setBackLocation(fieldValues.get(KRADConstants.BACK_LOCATION));
137            setDocFormKey(fieldValues.get(KRADConstants.DOC_FORM_KEY));
138            setReferencesToRefresh(fieldValues.get(KRADConstants.REFERENCES_TO_REFRESH));
139            if (LOG.isInfoEnabled()) {
140                    LOG.info("Search Criteria: " + fieldValues);
141            }
142            
143            //replace principal name with principal id in fieldValues
144            List searchResults;
145            searchResults = (List) getLookupService().findCollectionBySearchHelper(getBusinessObjectClass(), fieldValues, true);
146            // sort list if default sort column given
147            List defaultSortColumns = getDefaultSortColumns();
148            if (defaultSortColumns.size() > 0) {
149                Collections.sort(searchResults, new BeanPropertyComparator(getDefaultSortColumns(), true));
150            }
151            return searchResults;
152        }
153    
154        @Override
155        public void validateSearchParameters(Map<String, String> fieldValues) {
156            super.validateSearchParameters(fieldValues);
157            if (StringUtils.isNotEmpty((String)fieldValues.get(OWNER_PRINCIPAL_NAME_PROPERTY_NAME))) {
158                Person person = KimApiServiceLocator.getPersonService().getPersonByPrincipalName((String)fieldValues.get(OWNER_PRINCIPAL_NAME_PROPERTY_NAME));
159                if (person == null) {
160                    String attributeLabel = getDataDictionaryService().getAttributeLabel(getBusinessObjectClass(), OWNER_PRINCIPAL_NAME_PROPERTY_NAME);
161                    GlobalVariables.getMessageMap().putError(OWNER_PRINCIPAL_NAME_PROPERTY_NAME, RiceKeyConstants.ERROR_EXISTENCE, attributeLabel);
162                } 
163            }
164        }
165    
166    }
167