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.kew.api.KewApiServiceLocator;
020import org.kuali.rice.kew.api.doctype.DocumentType;
021import org.kuali.rice.kew.api.doctype.DocumentTypeService;
022import org.kuali.rice.kim.api.KimConstants;
023import org.kuali.rice.kim.api.permission.Permission;
024import org.kuali.rice.kim.impl.permission.PermissionBo;
025import org.kuali.rice.kns.kim.permission.PermissionTypeServiceBase;
026
027import java.util.ArrayList;
028import java.util.Collections;
029import java.util.HashSet;
030import java.util.List;
031import java.util.Map;
032import java.util.Set;
033
034/**
035 * This is a description of what this class does - mpham don't forget to fill
036 * this in.
037 * 
038 * @author Kuali Rice Team (rice.collab@kuali.org)
039 * 
040 */
041public class DocumentTypePermissionTypeServiceImpl extends PermissionTypeServiceBase {
042        protected transient DocumentTypeService documentTypeService;
043
044    @Override
045    protected List<String> getRequiredAttributes() {
046        return Collections.singletonList(KimConstants.AttributeConstants.DOCUMENT_TYPE_NAME);
047    }
048
049    @Override
050    protected boolean isCheckRequiredAttributes() {
051        return true;
052    }
053
054        /**
055         * Loops over the given permissions and returns the most specific permission that matches.
056         * 
057         * That is, if a permission exists for the document type, then the permission for any 
058         * parent document will not be considered/returned.
059         *
060         */
061        @Override
062        protected List<Permission> performPermissionMatches(Map<String, String> requestedDetails,
063            List<Permission> permissionsList) {
064                // pull all the potential parent doc type names from the permission list
065                Set<String> permissionDocTypeNames = new HashSet<String>( permissionsList.size() );
066                for ( Permission permission : permissionsList ) {
067            PermissionBo bo = PermissionBo.from(permission);
068                        String docTypeName = bo.getDetails().get( KimConstants.AttributeConstants.DOCUMENT_TYPE_NAME );
069                        if ( StringUtils.isNotBlank( docTypeName ) ) {
070                                permissionDocTypeNames.add( docTypeName );
071                        }
072                }
073                // find the parent documents which match
074                DocumentType docType = getDocumentTypeService().getDocumentTypeByName(requestedDetails.get(KimConstants.AttributeConstants.DOCUMENT_TYPE_NAME));
075                String matchingDocTypeName = getClosestParentDocumentTypeName(docType, permissionDocTypeNames);
076                // re-loop over the permissions and build a new list of the ones which have the
077                // matching document type names in their details
078                List<Permission> matchingPermissions = new ArrayList<Permission>();
079                for ( Permission kpi : permissionsList ) {
080            PermissionBo bo = PermissionBo.from(kpi);
081                        String docTypeName = bo.getDetails().get( KimConstants.AttributeConstants.DOCUMENT_TYPE_NAME );
082                        // only allow a match on the "*" type if no matching document types were found
083                        if((StringUtils.isEmpty(matchingDocTypeName) && StringUtils.equals(docTypeName,"*")) 
084                                || (StringUtils.isNotEmpty(matchingDocTypeName) && matchingDocTypeName.equals(docTypeName))) {
085                                matchingPermissions.add( kpi );
086                        }
087                }
088
089                return matchingPermissions;
090        }
091        
092        protected DocumentTypeService getDocumentTypeService() {
093                if ( documentTypeService == null ) {
094                        documentTypeService = KewApiServiceLocator.getDocumentTypeService();
095                }
096                return this.documentTypeService;
097        }
098
099}