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.kim.lookup;
017
018import org.apache.commons.lang.StringUtils;
019import org.kuali.rice.kew.api.KewApiConstants;
020import org.kuali.rice.kim.api.KimConstants;
021import org.kuali.rice.kim.api.identity.Person;
022import org.kuali.rice.kim.impl.KIMPropertyConstants;
023import org.kuali.rice.kim.impl.identity.PersonImpl;
024import org.kuali.rice.kim.util.KimCommonUtilsInternal;
025import org.kuali.rice.kns.lookup.HtmlData;
026import org.kuali.rice.kns.web.ui.Field;
027import org.kuali.rice.kns.web.ui.Row;
028import org.kuali.rice.krad.bo.BusinessObject;
029import org.kuali.rice.krad.util.KRADConstants;
030import org.kuali.rice.krad.util.UrlFactory;
031
032import java.util.ArrayList;
033import java.util.Iterator;
034import java.util.List;
035import java.util.Map;
036import java.util.Properties;
037
038/**
039 * This is a description of what this class does - shyu don't forget to fill this in. 
040 * 
041 * @author Kuali Rice Team (rice.collab@kuali.org)
042 *
043 */
044public class PersonLookupableHelperServiceImpl  extends KimLookupableHelperServiceImpl {
045        
046        private static final long serialVersionUID = 1971744785776844579L;
047        
048        @Override
049        public List<? extends BusinessObject> getSearchResults(
050                        Map<String, String> fieldValues) {
051                if (fieldValues != null && StringUtils.isNotEmpty(fieldValues.get(KIMPropertyConstants.Person.PRINCIPAL_NAME))) {
052                        fieldValues.put(KIMPropertyConstants.Person.PRINCIPAL_NAME, fieldValues.get(KIMPropertyConstants.Person.PRINCIPAL_NAME).toLowerCase());
053                }
054
055                return super.getSearchResults(fieldValues);
056        }
057
058        @SuppressWarnings("unchecked")
059        @Override
060        public List<HtmlData> getCustomActionUrls(BusinessObject bo, List pkNames) {
061        List<HtmlData> anchorHtmlDataList = new ArrayList<HtmlData>();
062                if(allowsNewOrCopyAction(KimConstants.KimUIConstants.KIM_PERSON_DOCUMENT_TYPE_NAME)){
063                        String href = "";
064                        Properties parameters = new Properties();
065                parameters.put(KRADConstants.DISPATCH_REQUEST_PARAMETER, KRADConstants.DOC_HANDLER_METHOD);
066                parameters.put(KRADConstants.PARAMETER_COMMAND, KewApiConstants.INITIATE_COMMAND);
067                parameters.put(KRADConstants.DOCUMENT_TYPE_NAME, KimConstants.KimUIConstants.KIM_PERSON_DOCUMENT_TYPE_NAME);
068                parameters.put(KimConstants.PrimaryKeyConstants.PRINCIPAL_ID, ((PersonImpl)bo).getPrincipalId());
069                if (StringUtils.isNotBlank(getReturnLocation())) {
070                        parameters.put(KRADConstants.RETURN_LOCATION_PARAMETER, getReturnLocation());
071                        }
072                href = UrlFactory.parameterizeUrl(KimCommonUtilsInternal.getKimBasePath()+KimConstants.KimUIConstants.KIM_PERSON_DOCUMENT_ACTION, parameters);
073        
074                HtmlData.AnchorHtmlData anchorHtmlData = new HtmlData.AnchorHtmlData(href,
075                                KRADConstants.DOC_HANDLER_METHOD, KRADConstants.MAINTENANCE_EDIT_METHOD_TO_CALL);
076        
077                anchorHtmlDataList.add(anchorHtmlData);
078                }
079        return anchorHtmlDataList;
080        }
081
082        @Override
083        public HtmlData getInquiryUrl(BusinessObject bo, String propertyName) {
084                HtmlData inqUrl = super.getInquiryUrl(bo, propertyName);
085                Properties parameters = new Properties();
086        parameters.put(KewApiConstants.COMMAND_PARAMETER, KewApiConstants.INITIATE_COMMAND);
087        parameters.put(KRADConstants.DOCUMENT_TYPE_NAME, KimConstants.KimUIConstants.KIM_PERSON_DOCUMENT_TYPE_NAME);
088        parameters.put(KimConstants.PrimaryKeyConstants.PRINCIPAL_ID, ((Person)bo).getPrincipalId());
089        String href = UrlFactory.parameterizeUrl(KimCommonUtilsInternal.getKimBasePath()+ KimConstants.KimUIConstants.KIM_PERSON_INQUIRY_ACTION, parameters);
090            ((HtmlData.AnchorHtmlData)inqUrl).setHref(href);
091            return inqUrl;
092        }
093        
094        /**
095         * Checks for the special role lookup parameters and removes/marks read-only the fields in the search criteria.
096         * If present, this method also has a side-effect of updating the title with the role name.
097         * 
098         * @see org.kuali.rice.krad.lookup.AbstractLookupableHelperServiceImpl#getRows()
099         */
100        @Override
101        public List<Row> getRows() {
102                title.remove(); 
103                List<Row> rows = super.getRows();
104                Iterator<Row> i = rows.iterator();
105                String roleName = null;
106                String namespaceCode = null;
107                while ( i.hasNext() ) {
108                        Row row = i.next();
109                        int numFieldsRemoved = 0;
110                        boolean rowIsBlank = true;
111                        // Since multi-column lookups can be specified on Rice lookups, all the fields in each row must be iterated over as well,
112                        // just in case the person lookup ever gets configured to have multiple columns per row.
113                        for (Iterator<Field> fieldIter = row.getFields().iterator(); fieldIter.hasNext();) {
114                            Field field = fieldIter.next();
115                            String propertyName = field.getPropertyName();
116                            if ( propertyName.equals("lookupRoleName") ) {
117                                    Object val = getParameters().get( propertyName );
118                                    String propVal = null;
119                                    if ( val != null ) {
120                                            propVal = (val instanceof String)?(String)val:((String[])val)[0];
121                                    }
122                                    if ( StringUtils.isBlank( propVal ) ) {
123                                            fieldIter.remove();
124                                            numFieldsRemoved++;
125                                    } else {
126                                            field.setReadOnly(true);
127                                            field.setDefaultValue( propVal );
128                                            roleName = propVal;
129                                            rowIsBlank = false;
130                                    }
131                            } else if ( propertyName.equals("lookupRoleNamespaceCode") ) {
132                                    Object val = getParameters().get( propertyName );
133                                    String propVal = null;
134                                    if ( val != null ) {
135                                            propVal = (val instanceof String)?(String)val:((String[])val)[0];
136                                    }
137                                    if ( StringUtils.isBlank( propVal ) ) {
138                                            fieldIter.remove();
139                                            numFieldsRemoved++;
140                                    } else {
141                                            field.setReadOnly(true);
142                                            field.setDefaultValue( propVal );
143                                            namespaceCode = propVal;
144                                            rowIsBlank = false;
145                                    }                           
146                            } else if (!Field.BLANK_SPACE.equals(field.getFieldType())) {
147                                rowIsBlank = false;
148                            }
149                        }
150                        // Check if any fields were removed from the row.
151                        if (numFieldsRemoved > 0) {
152                                // If fields were removed, check whether or not the remainder of the row is empty or only has blank space fields.
153                                if (rowIsBlank) {
154                                        // If so, then remove the row entirely.
155                                        i.remove();
156                                } else {
157                                        // Otherwise, add one blank space for each field that was removed, using a technique similar to FieldUtils.createBlankSpace.
158                                        // It is safe to just add blank spaces as needed, since the two removable fields are the last of the visible ones in the list.
159                                        while (numFieldsRemoved > 0) {
160                                                Field blankSpace = new Field();
161                                                blankSpace.setFieldType(Field.BLANK_SPACE);
162                                                blankSpace.setPropertyName(Field.BLANK_SPACE);
163                                                row.getFields().add(blankSpace);
164                                                numFieldsRemoved--;
165                                        }
166                                }
167                        }
168                }
169                if ( roleName != null && namespaceCode != null ) {
170                        title.set( namespaceCode + " " + roleName + " Lookup" );
171                }
172                return rows;
173        }
174        
175        private ThreadLocal<String> title = new ThreadLocal<String>();
176        public String getTitle() {
177                if ( title.get() == null ) {
178                        return super.getTitle();
179                }
180                return title.get();
181        }
182}