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.krad.kim;
017
018import org.apache.commons.lang.StringUtils;
019import org.kuali.rice.kim.api.KimConstants;
020import org.kuali.rice.kim.api.permission.Permission;
021import org.kuali.rice.kim.impl.permission.PermissionBo;
022import org.kuali.rice.krad.kim.DocumentTypePermissionTypeServiceImpl;
023
024import java.util.ArrayList;
025import java.util.List;
026import java.util.Map;
027
028/**
029 * 
030 * @author Kuali Rice Team (rice.collab@kuali.org)
031 *
032 */
033public class DocumentTypeAndNodeAndFieldsPermissionTypeServiceImpl extends DocumentTypePermissionTypeServiceImpl {
034
035    @Override
036    protected boolean isCheckRequiredAttributes() {
037        return true;
038    }
039
040        /**
041         * 
042         *      consider the document type hierarchy - check for a permission that just specifies the document type first at each level 
043         *      - then if you don't find that, check for the doc type and the node, then the doc type and the field.
044         *
045         *      - if the field value passed in starts with the value on the permission detail it is a match.  so...
046         *      permision detail sourceAccountingLines will match passed in value of sourceAccountingLines.amount and sourceAccountingLines 
047         *      permission detail sourceAccountingLines.objectCode will match sourceAccountingLines.objectCode but not sourceAccountingLines
048         */
049        @Override
050        protected List<Permission> performPermissionMatches(Map<String, String> requestedDetails,
051                        List<Permission> permissionsList) {
052
053        List<Permission> matchingPermissions = new ArrayList<Permission>();
054                // loop over the permissions, checking the non-document-related ones
055                for ( Permission kpi : permissionsList ) {
056            PermissionBo bo = PermissionBo.from(kpi);
057                        if ( routeNodeMatches(requestedDetails, bo.getDetails()) &&
058                                        doesPropertyNameMatch(requestedDetails.get(KimConstants.AttributeConstants.PROPERTY_NAME), bo.getDetails().get(KimConstants.AttributeConstants.PROPERTY_NAME)) ) {
059                                matchingPermissions.add( kpi );
060                        }                       
061                }
062                // now, filter the list to just those for the current document
063                matchingPermissions = super.performPermissionMatches( requestedDetails, matchingPermissions );
064                return matchingPermissions;
065        }
066                
067        protected boolean routeNodeMatches(Map<String, String> requestedDetails, Map<String, String> permissionDetails) {
068                if ( StringUtils.isBlank( permissionDetails.get(KimConstants.AttributeConstants.ROUTE_NODE_NAME) ) ) {
069                        return true;
070                }
071                return StringUtils.equals(requestedDetails.get(KimConstants.AttributeConstants.ROUTE_NODE_NAME), permissionDetails.get(
072                KimConstants.AttributeConstants.ROUTE_NODE_NAME));
073        }
074}