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.krad.kim;
017    
018    import org.apache.commons.lang.StringUtils;
019    import org.kuali.rice.kim.api.KimConstants;
020    import org.kuali.rice.kim.api.permission.Permission;
021    import org.kuali.rice.kim.impl.permission.PermissionBo;
022    import org.kuali.rice.kns.kim.permission.PermissionTypeServiceBase;
023    
024    import java.util.ArrayList;
025    import java.util.Collections;
026    import java.util.List;
027    import java.util.Map;
028    
029    /**
030     * Type service for the 'View' KIM type which matches on the id for a UIF view
031     *
032     * @author Kuali Rice Team (rice.collab@kuali.org)
033     */
034    public class ViewPermissionTypeServiceImpl extends PermissionTypeServiceBase {
035        private boolean exactMatchPriority = true;
036    
037        @Override
038        protected List<String> getRequiredAttributes() {
039            List<String> attributes = new ArrayList<String>(super.getRequiredAttributes());
040            attributes.add(KimConstants.AttributeConstants.VIEW_ID);
041    
042            return Collections.unmodifiableList(attributes);
043        }
044    
045        /**
046         * Filters the given permission list to return those that match the view id qualifier
047         *
048         * <p>
049         * By default, this method will return all exact matches if any exist, and it will only return partial matches
050         * if there are no exact matches. i.e. KR-DocumentView will have priority over KR-*. If ExactMatchPriority is
051         * false, then this method will return all exact AND partial matching permissions.  By default, ExactMatchPriority
052         * will be set to true.
053         * </p>
054         *
055         * @param requestedDetails - map of details requested with permission (used for matching)
056         * @param permissionsList - list of permissions to process for matches
057         * @return List<Permission> list of permissions that match the requested details
058         */
059        @Override
060        protected List<Permission> performPermissionMatches(Map<String, String> requestedDetails,
061                List<Permission> permissionsList) {
062            List<Permission> matchingPermissions = new ArrayList<Permission>();
063    
064            String requestedViewId = requestedDetails.get(KimConstants.AttributeConstants.VIEW_ID);
065    
066            // add all exact matches to the list
067            for (Permission permission : permissionsList) {
068                PermissionBo bo = PermissionBo.from(permission);
069    
070                String permissionViewId = bo.getDetails().get(KimConstants.AttributeConstants.VIEW_ID);
071                if (StringUtils.equals(requestedViewId, permissionViewId)) {
072                    matchingPermissions.add(permission);
073                }
074            }
075    
076            // add partial matches to the list if there are no exact matches or if exactMatchPriority is false
077            if ((exactMatchPriority && matchingPermissions.isEmpty()) || (!(exactMatchPriority))) {
078                for (Permission kpi : permissionsList) {
079                    PermissionBo bo = PermissionBo.from(kpi);
080    
081                    String permissionViewId = bo.getDetails().get(KimConstants.AttributeConstants.VIEW_ID);
082                    if (requestedViewId != null && permissionViewId != null && (!(StringUtils.equals(requestedViewId,
083                            permissionViewId))) && requestedViewId.matches(permissionViewId.replaceAll("\\*", ".*"))) {
084                        matchingPermissions.add(kpi);
085                    }
086                }
087            }
088    
089            return matchingPermissions;
090        }
091    
092        /**
093         * Indicates whether permissions with details that exactly match the requested details have priority over
094         * permissions with details that partially match (based on wildcard match). Default is set to true
095         *
096         * @return boolean true if exact matches should be given priority, false if not
097         */
098        public boolean getExactMatchPriority() {
099            return this.exactMatchPriority;
100        }
101    
102        /**
103         * Setter for the exact match priority indicator
104         *
105         * @param exactMatchPriority
106         */
107        public void setExactMatchPriority(Boolean exactMatchPriority) {
108            this.exactMatchPriority = exactMatchPriority;
109        }
110    }