View Javadoc

1   /*
2    * Copyright 2007-2008 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.kim.service.impl;
17  
18  import java.util.ArrayList;
19  import java.util.Collection;
20  import java.util.Collections;
21  import java.util.Comparator;
22  import java.util.HashMap;
23  import java.util.List;
24  import java.util.Map;
25  
26  import javax.jws.WebService;
27  
28  import org.apache.commons.lang.StringUtils;
29  import org.apache.log4j.Logger;
30  import org.kuali.rice.core.xml.dto.AttributeSet;
31  import org.kuali.rice.kim.bo.Role;
32  import org.kuali.rice.kim.bo.impl.PermissionImpl;
33  import org.kuali.rice.kim.bo.role.dto.KimPermissionInfo;
34  import org.kuali.rice.kim.bo.role.dto.KimPermissionTemplateInfo;
35  import org.kuali.rice.kim.bo.role.dto.PermissionAssigneeInfo;
36  import org.kuali.rice.kim.bo.role.dto.RoleMembershipInfo;
37  import org.kuali.rice.kim.bo.role.impl.KimPermissionImpl;
38  import org.kuali.rice.kim.bo.role.impl.KimPermissionTemplateImpl;
39  import org.kuali.rice.kim.bo.types.dto.AttributeDefinitionMap;
40  import org.kuali.rice.kim.bo.types.dto.KimTypeInfo;
41  import org.kuali.rice.kim.dao.KimPermissionDao;
42  import org.kuali.rice.kim.service.KIMServiceLocator;
43  import org.kuali.rice.kim.service.KIMServiceLocatorInternal;
44  import org.kuali.rice.kim.service.KIMServiceLocatorWeb;
45  import org.kuali.rice.kim.service.PermissionService;
46  import org.kuali.rice.kim.service.RoleService;
47  import org.kuali.rice.kim.service.support.KimPermissionTypeService;
48  import org.kuali.rice.kim.util.KIMWebServiceConstants;
49  import org.kuali.rice.kim.util.KimConstants;
50  import org.kuali.rice.kns.datadictionary.AttributeDefinition;
51  import org.kuali.rice.kns.lookup.CollectionIncomplete;
52  import org.kuali.rice.kns.lookup.Lookupable;
53  import org.kuali.rice.kns.service.DataDictionaryService;
54  import org.kuali.rice.kns.service.KNSServiceLocatorWeb;
55  import org.kuali.rice.kns.util.KNSPropertyConstants;
56  
57  /**
58   * This is a description of what this class does - jonathan don't forget to fill this in. 
59   * 
60   * @author Kuali Rice Team (rice.collab@kuali.org)
61   *
62   */
63  @WebService(endpointInterface = KIMWebServiceConstants.PermissionService.INTERFACE_CLASS, serviceName = KIMWebServiceConstants.PermissionService.WEB_SERVICE_NAME, portName = KIMWebServiceConstants.PermissionService.WEB_SERVICE_PORT, targetNamespace = KIMWebServiceConstants.MODULE_TARGET_NAMESPACE)
64  public class PermissionServiceImpl extends PermissionServiceBase implements PermissionService {
65  	private static final Logger LOG = Logger.getLogger( PermissionServiceImpl.class );
66  
67  	private RoleService roleService;
68  	private KimPermissionDao permissionDao;
69      private KimPermissionTypeService defaultPermissionTypeService;
70  	
71  	private List<KimPermissionTemplateInfo> allTemplates;
72  	
73      // --------------------
74      // Authorization Checks
75      // --------------------
76      
77  	protected KimPermissionTypeService getPermissionTypeService( String namespaceCode, String permissionTemplateName, String permissionName, String permissionId ) {
78  		StringBuffer cacheKey = new StringBuffer();
79  		if ( namespaceCode != null ) {
80  			cacheKey.append( namespaceCode );
81  		}
82  		cacheKey.append( '|' );
83  		if ( permissionTemplateName != null ) {
84  			cacheKey.append( permissionTemplateName );
85  		}
86  		cacheKey.append( '|' );
87  		if ( permissionName != null ) {
88  			cacheKey.append( permissionName );
89  		}
90  		cacheKey.append( '|' );
91  		if ( permissionId != null ) {
92  			cacheKey.append( permissionId );
93  		}
94  		String key = cacheKey.toString();
95  		KimPermissionTypeService service = getPermissionTypeServiceByNameCache().get(key);
96  		if ( service == null ) {
97  			KimPermissionTemplateImpl permTemplate = null;
98  			if ( permissionTemplateName != null ) {
99  				List<KimPermissionImpl> perms = getPermissionImplsByTemplateName(namespaceCode, permissionTemplateName);
100 				if ( !perms.isEmpty() ) {
101 					permTemplate = perms.get(0).getTemplate();
102 				}
103 			} else if ( permissionName != null ) {
104 				List<KimPermissionImpl> perms = getPermissionImplsByName(namespaceCode, permissionName); 
105 				if ( !perms.isEmpty() ) {
106 					permTemplate = perms.get(0).getTemplate();
107 				}
108 			} else if ( permissionId != null ) {
109 				KimPermissionImpl perm = getPermissionImpl(permissionId);
110 				if ( perm != null ) {
111 					permTemplate = perm.getTemplate();
112 				}
113 			}
114 			service = getPermissionTypeService( permTemplate );
115 			getPermissionTypeServiceByNameCache().put(key, service);
116 		}
117 		return service;
118 	}
119 
120     protected KimPermissionTypeService getPermissionTypeService( KimPermissionTemplateImpl permissionTemplate ) {
121     	if ( permissionTemplate == null ) {
122     		throw new IllegalArgumentException( "permissionTemplate may not be null" );
123     	}
124     	KimTypeInfo kimType = KIMServiceLocatorWeb.getTypeInfoService().getKimType( permissionTemplate.getKimTypeId() );
125     	String serviceName = kimType.getKimTypeServiceName();
126     	// if no service specified, return a default implementation
127     	if ( StringUtils.isBlank( serviceName ) ) {
128     		return getDefaultPermissionTypeService();
129     	}
130     	try {
131 	    	Object service = KIMServiceLocatorInternal.getService(serviceName);
132 	    	// if we have a service name, it must exist
133 	    	if ( service == null ) {
134 				throw new RuntimeException("null returned for permission type service for service name: " + serviceName);
135 	    	}
136 	    	// whatever we retrieved must be of the correct type
137 	    	if ( !(service instanceof KimPermissionTypeService)  ) {
138 	    		throw new RuntimeException( "Service " + serviceName + " was not a KimPermissionTypeService.  Was: " + service.getClass().getName() );
139 	    	}
140 	    	return (KimPermissionTypeService)service;
141     	} catch( Exception ex ) {
142     		// sometimes service locators throw exceptions rather than returning null, handle that
143     		throw new RuntimeException( "Error retrieving service: " + serviceName + " from the KIMServiceLocatorInternal.", ex );
144     	}
145     }
146     
147     protected KimPermissionTypeService getDefaultPermissionTypeService() {
148     	if ( defaultPermissionTypeService == null ) {
149     		defaultPermissionTypeService = (KimPermissionTypeService) KIMServiceLocatorInternal.getBean(DEFAULT_PERMISSION_TYPE_SERVICE);
150     	}
151 		return defaultPermissionTypeService;
152 	}
153 	
154     /**
155      * @see org.kuali.rice.kim.service.PermissionService#hasPermission(java.lang.String, String, java.lang.String, AttributeSet)
156      */
157     public boolean hasPermission(String principalId, String namespaceCode, String permissionName, AttributeSet permissionDetails) {
158     	return isAuthorized( principalId, namespaceCode, permissionName, permissionDetails, null );
159     }
160 
161     /**
162      * @see org.kuali.rice.kim.service.PermissionService#isAuthorized( java.lang.String, String, java.lang.String, AttributeSet, AttributeSet)
163      */
164     public boolean isAuthorized(String principalId, String namespaceCode, String permissionName, AttributeSet permissionDetails, AttributeSet qualification ) {
165     	List<String> roleIds = getRoleIdsForPermission( namespaceCode, permissionName, permissionDetails );
166     	if ( roleIds.isEmpty() ) {
167     		return false;
168     	}
169 		return getRoleService().principalHasRole( principalId, roleIds, qualification );
170     }
171 
172     /**
173      * @see org.kuali.rice.kim.service.PermissionService#hasPermission(String, String, String, AttributeSet)
174      */
175     public boolean hasPermissionByTemplateName(String principalId, String namespaceCode, String permissionTemplateName, AttributeSet permissionDetails) {
176     	return isAuthorizedByTemplateName( principalId, namespaceCode, permissionTemplateName, permissionDetails, null );
177     }
178 
179     /**
180      * @see org.kuali.rice.kim.service.PermissionService#isAuthorized( java.lang.String, String, java.lang.String, AttributeSet, AttributeSet)
181      */
182     public boolean isAuthorizedByTemplateName(String principalId, String namespaceCode, String permissionTemplateName, AttributeSet permissionDetails, AttributeSet qualification ) {
183     	List<String> roleIds = getRoleIdsForPermissionTemplate( namespaceCode, permissionTemplateName, permissionDetails );
184     	if ( roleIds.isEmpty() ) {
185     		return false;
186     	}
187     	return getRoleService().principalHasRole( principalId, roleIds, qualification );
188     }
189 
190     /**
191      * @see org.kuali.rice.kim.service.PermissionService#getAuthorizedPermissions(String, String, String, AttributeSet, AttributeSet)
192      */
193     public List<KimPermissionInfo> getAuthorizedPermissions( String principalId, String namespaceCode, String permissionName, AttributeSet permissionDetails, AttributeSet qualification ) {
194     	// get all the permission objects whose name match that requested
195     	List<KimPermissionImpl> permissions = getPermissionImplsByName( namespaceCode, permissionName );
196     	// now, filter the full list by the detail passed
197     	List<KimPermissionInfo> applicablePermissions = getMatchingPermissions( permissions, permissionDetails );  
198     	return getPermissionsForUser(principalId, applicablePermissions, qualification);
199     }
200 
201     /**
202      * @see org.kuali.rice.kim.service.PermissionService#getAuthorizedPermissionsByTemplateName(String, String, String, AttributeSet, AttributeSet)
203      */
204     public List<KimPermissionInfo> getAuthorizedPermissionsByTemplateName( String principalId, String namespaceCode, String permissionTemplateName, AttributeSet permissionDetails, AttributeSet qualification ) {
205     	// get all the permission objects whose name match that requested
206     	List<KimPermissionImpl> permissions = getPermissionImplsByTemplateName( namespaceCode, permissionTemplateName );
207     	// now, filter the full list by the detail passed
208     	List<KimPermissionInfo> applicablePermissions = getMatchingPermissions( permissions, permissionDetails );  
209     	return getPermissionsForUser(principalId, applicablePermissions, qualification);
210     }
211     
212     /**
213      * Checks the list of permissions against the principal's roles and returns a subset of the list which match.
214      */
215     protected List<KimPermissionInfo> getPermissionsForUser( String principalId, List<KimPermissionInfo> permissions, AttributeSet qualification ) {
216     	ArrayList<KimPermissionInfo> results = new ArrayList<KimPermissionInfo>();
217     	List<KimPermissionInfo> tempList = new ArrayList<KimPermissionInfo>(1);
218     	for ( KimPermissionInfo perm : permissions ) {
219     		tempList.clear();
220     		tempList.add( perm );
221     		List<String> roleIds = permissionDao.getRoleIdsForPermissions( tempList );
222     		// TODO: This could be made a little better by collecting the role IDs into
223     		// a set and then processing the distinct list rather than a check
224     		// for every permission
225     		if ( roleIds != null && !roleIds.isEmpty() ) {
226     			if ( getRoleService().principalHasRole( principalId, roleIds, qualification ) ) {
227     				results.add( perm );
228     			}
229     		}
230     	}
231     	
232     	return results;    	
233     }
234 
235     protected Map<String,KimPermissionTypeService> getPermissionTypeServicesByTemplateId( Collection<KimPermissionImpl> permissions ) {
236     	Map<String,KimPermissionTypeService> permissionTypeServices = new HashMap<String, KimPermissionTypeService>( permissions.size() );
237     	for ( KimPermissionImpl perm : permissions ) {
238     		permissionTypeServices.put(perm.getTemplateId(), getPermissionTypeService( perm.getTemplate() ) );    				
239     	}
240     	return permissionTypeServices;
241     }
242     
243     protected Map<String,List<KimPermissionInfo>> groupPermissionsByTemplate( Collection<KimPermissionImpl> permissions ) {
244     	Map<String,List<KimPermissionInfo>> results = new HashMap<String,List<KimPermissionInfo>>();
245     	for ( KimPermissionImpl perm : permissions ) {
246     		List<KimPermissionInfo> perms = results.get( perm.getTemplateId() );
247     		if ( perms == null ) {
248     			perms = new ArrayList<KimPermissionInfo>();
249     			results.put( perm.getTemplateId(), perms );
250     		}
251     		perms.add( perm.toSimpleInfo() );
252     	}
253     	return results;
254     }
255     
256 	/**
257      * Compare each of the passed in permissions with the given permissionDetails.  Those that
258      * match are added to the result list.
259      */
260     protected List<KimPermissionInfo> getMatchingPermissions( List<KimPermissionImpl> permissions, AttributeSet permissionDetails ) {
261     	List<KimPermissionInfo> applicablePermissions = new ArrayList<KimPermissionInfo>();    	
262     	if ( permissionDetails == null || permissionDetails.isEmpty() ) {
263     		// if no details passed, assume that all match
264     		for ( KimPermissionImpl perm : permissions ) {
265     			applicablePermissions.add( perm.toSimpleInfo() );
266     		}
267     	} else {
268     		// otherwise, attempt to match the permission details
269     		// build a map of the template IDs to the type services
270     		Map<String,KimPermissionTypeService> permissionTypeServices = getPermissionTypeServicesByTemplateId( permissions );
271     		// build a map of permissions by template ID
272     		Map<String,List<KimPermissionInfo>> permissionMap = groupPermissionsByTemplate( permissions );
273     		// loop over the different templates, matching all of the same template against the type
274     		// service at once
275     		for ( String templateId : permissionMap.keySet() ) {
276     			KimPermissionTypeService permissionTypeService = permissionTypeServices.get( templateId );
277     			List<KimPermissionInfo> permissionList = permissionMap.get( templateId );
278 				applicablePermissions.addAll( permissionTypeService.getMatchingPermissions( permissionDetails, permissionList ) );    				
279     		}
280     	}
281     	return applicablePermissions;
282     }
283 
284     /**
285      * @see org.kuali.rice.kim.service.PermissionService#getPermissionAssignees(String, String, AttributeSet, AttributeSet)
286      */
287     public List<PermissionAssigneeInfo> getPermissionAssignees( String namespaceCode, String permissionName, AttributeSet permissionDetails, AttributeSet qualification ) {
288     	List<PermissionAssigneeInfo> results = new ArrayList<PermissionAssigneeInfo>();
289     	List<String> roleIds = getRoleIdsForPermission( namespaceCode, permissionName, permissionDetails);
290     	if ( roleIds.isEmpty() ) {
291     		return results;
292     	}
293     	Collection<RoleMembershipInfo> roleMembers = getRoleService().getRoleMembers( roleIds, qualification );
294     	for ( RoleMembershipInfo rm : roleMembers ) {
295     		if ( rm.getMemberTypeCode().equals( Role.PRINCIPAL_MEMBER_TYPE ) ) {
296     			results.add( new PermissionAssigneeInfo( rm.getMemberId(), null, rm.getDelegates() ) );
297     		} else if ( rm.getMemberTypeCode().equals( Role.GROUP_MEMBER_TYPE ) ) {
298     			results.add( new PermissionAssigneeInfo( null, rm.getMemberId(), rm.getDelegates() ) );
299     		}
300     	}
301     	return results;
302     }
303     
304     public List<PermissionAssigneeInfo> getPermissionAssigneesForTemplateName( String namespaceCode, String permissionTemplateName, AttributeSet permissionDetails, AttributeSet qualification ) {
305     	List<PermissionAssigneeInfo> results = new ArrayList<PermissionAssigneeInfo>();
306     	List<String> roleIds = getRoleIdsForPermissionTemplate( namespaceCode, permissionTemplateName, permissionDetails);
307     	if ( roleIds.isEmpty() ) {
308     		return results;
309     	}
310     	Collection<RoleMembershipInfo> roleMembers = getRoleService().getRoleMembers( roleIds, qualification );
311     	for ( RoleMembershipInfo rm : roleMembers ) {
312     		if ( rm.getMemberTypeCode().equals( Role.PRINCIPAL_MEMBER_TYPE ) ) {
313     			results.add( new PermissionAssigneeInfo( rm.getMemberId(), null, rm.getDelegates() ) );
314     		} else { // a group membership
315     			results.add( new PermissionAssigneeInfo( null, rm.getMemberId(), rm.getDelegates() ) );
316     		}
317     	}
318     	return results;
319     }
320     
321     public boolean isPermissionAssigned( String namespaceCode, String permissionName, AttributeSet permissionDetails ) {
322     	return !getRoleIdsForPermission(namespaceCode, permissionName, permissionDetails).isEmpty();
323     }
324     
325     public boolean isPermissionDefined( String namespaceCode, String permissionName, AttributeSet permissionDetails ) {
326     	// get all the permission objects whose name match that requested
327     	List<KimPermissionImpl> permissions = getPermissionImplsByName( namespaceCode, permissionName );
328     	// now, filter the full list by the detail passed
329     	return !getMatchingPermissions( permissions, permissionDetails ).isEmpty();   
330     }
331     
332     public boolean isPermissionDefinedForTemplateName( String namespaceCode, String permissionTemplateName, AttributeSet permissionDetails ) {
333     	// get all the permission objects whose name match that requested
334     	List<KimPermissionImpl> permissions = getPermissionImplsByTemplateName( namespaceCode, permissionTemplateName );
335     	// now, filter the full list by the detail passed
336     	return !getMatchingPermissions( permissions, permissionDetails ).isEmpty();   
337     }
338  
339     public List<String> getRoleIdsForPermission( String namespaceCode, String permissionName, AttributeSet permissionDetails) {
340     	// get all the permission objects whose name match that requested
341     	List<KimPermissionImpl> permissions = getPermissionImplsByName( namespaceCode, permissionName );
342     	// now, filter the full list by the detail passed
343     	List<KimPermissionInfo> applicablePermissions = getMatchingPermissions( permissions, permissionDetails );    	
344     	List<String> roleIds = getRolesForPermissionsFromCache( applicablePermissions );
345     	if ( roleIds == null ) {
346     		roleIds = permissionDao.getRoleIdsForPermissions( applicablePermissions );
347     		addRolesForPermissionsToCache( applicablePermissions, roleIds );
348     	}
349     	return roleIds;    	
350     }
351 
352     protected List<String> getRoleIdsForPermissionTemplate( String namespaceCode, String permissionTemplateName, AttributeSet permissionDetails ) {
353     	// get all the permission objects whose name match that requested
354     	List<KimPermissionImpl> permissions = getPermissionImplsByTemplateName( namespaceCode, permissionTemplateName );
355     	// now, filter the full list by the detail passed
356     	List<KimPermissionInfo> applicablePermissions = getMatchingPermissions( permissions, permissionDetails );
357     	List<String> roleIds = getRolesForPermissionsFromCache( applicablePermissions );
358     	if ( roleIds == null ) {
359     		roleIds = permissionDao.getRoleIdsForPermissions( applicablePermissions );
360     		addRolesForPermissionsToCache( applicablePermissions, roleIds );
361     	}
362     	return roleIds;
363     }
364     
365     public List<String> getRoleIdsForPermissions( List<KimPermissionInfo> permissions ) {
366     	List<String> roleIds = getRolesForPermissionsFromCache( permissions );
367     	if ( roleIds == null ) {
368     		roleIds = permissionDao.getRoleIdsForPermissions( permissions );
369     		addRolesForPermissionsToCache( permissions, roleIds );
370     	}
371     	return roleIds;
372     }
373 
374     // --------------------
375     // Permission Data
376     // --------------------
377     
378     /**
379      * @see org.kuali.rice.kim.service.PermissionService#getPermission(java.lang.String)
380      */
381     public KimPermissionInfo getPermission(String permissionId) {
382     	KimPermissionImpl impl = getPermissionImpl( permissionId );
383     	if ( impl != null ) {
384     		return impl.toSimpleInfo();
385     	}
386     	return null;
387     }
388     
389     /**
390      * @see org.kuali.rice.kim.service.PermissionService#getPermissionsByTemplateName(String, String)
391      */
392     public List<KimPermissionInfo> getPermissionsByTemplateName(String namespaceCode, String permissionTemplateName) {
393     	List<KimPermissionImpl> impls = getPermissionImplsByTemplateName( namespaceCode, permissionTemplateName );
394     	List<KimPermissionInfo> results = new ArrayList<KimPermissionInfo>( impls.size() );
395     	for ( KimPermissionImpl impl : impls ) {
396     		results.add( impl.toSimpleInfo() );
397     	}
398     	return results;
399     }
400 
401 	/**
402      * @see org.kuali.rice.kim.service.PermissionService#getPermissionsByName(String, String)
403      */
404     public List<KimPermissionInfo> getPermissionsByName(String namespaceCode, String permissionName) {
405     	List<KimPermissionImpl> impls = getPermissionImplsByName( namespaceCode, permissionName );
406     	List<KimPermissionInfo> results = new ArrayList<KimPermissionInfo>( impls.size() );
407     	for ( KimPermissionImpl impl : impls ) {
408     		results.add( impl.toSimpleInfo() );
409     	}
410     	return results;
411     }
412     
413     @SuppressWarnings("unchecked")
414 	protected KimPermissionImpl getPermissionImpl(String permissionId) {
415     	if ( StringUtils.isBlank( permissionId ) ) {
416     		return null;
417     	}
418     	String cacheKey = getPermissionImplByIdCacheKey(permissionId);
419     	List<KimPermissionImpl> permissions = (List<KimPermissionImpl>)getCacheAdministrator().getFromCache(cacheKey);
420     	if ( permissions == null ) {
421 	    	HashMap<String,Object> pk = new HashMap<String,Object>( 1 );
422 	    	pk.put( KimConstants.PrimaryKeyConstants.PERMISSION_ID, permissionId );
423 	    	permissions = Collections.singletonList( (KimPermissionImpl)getBusinessObjectService().findByPrimaryKey( KimPermissionImpl.class, pk ) );
424 	    	getCacheAdministrator().putInCache(cacheKey, permissions, PERMISSION_IMPL_CACHE_GROUP);
425     	}
426     	return permissions.get( 0 );
427     }
428     
429     @SuppressWarnings("unchecked")
430 	protected List<KimPermissionImpl> getPermissionImplsByTemplateName( String namespaceCode, String permissionTemplateName ) {
431     	String cacheKey = getPermissionImplByTemplateNameCacheKey(namespaceCode, permissionTemplateName);
432     	List<KimPermissionImpl> permissions = (List<KimPermissionImpl>)getCacheAdministrator().getFromCache(cacheKey);
433     	if ( permissions == null ) {    	
434 	    	HashMap<String,Object> pk = new HashMap<String,Object>( 3 );
435 	    	pk.put( "template.namespaceCode", namespaceCode );
436 	    	pk.put( "template.name", permissionTemplateName );
437 			pk.put( KNSPropertyConstants.ACTIVE, "Y" );
438 	    	permissions = (List<KimPermissionImpl>)getBusinessObjectService().findMatching( KimPermissionImpl.class, pk );
439 	    	getCacheAdministrator().putInCache(cacheKey, permissions, PERMISSION_IMPL_CACHE_GROUP);
440     	}
441     	return permissions;
442     }
443 
444     @SuppressWarnings("unchecked")
445 	protected List<KimPermissionImpl> getPermissionImplsByName( String namespaceCode, String permissionName ) {
446     	String cacheKey = getPermissionImplByNameCacheKey(namespaceCode, permissionName);
447     	List<KimPermissionImpl> permissions = (List<KimPermissionImpl>)getCacheAdministrator().getFromCache(cacheKey);
448     	if ( permissions == null ) {
449 	    	HashMap<String,Object> pk = new HashMap<String,Object>( 3 );
450 	    	pk.put( KimConstants.UniqueKeyConstants.NAMESPACE_CODE, namespaceCode );
451 	    	pk.put( KimConstants.UniqueKeyConstants.PERMISSION_NAME, permissionName );
452 			pk.put( KNSPropertyConstants.ACTIVE, "Y" );
453 	    	permissions = (List<KimPermissionImpl>)getBusinessObjectService().findMatching( KimPermissionImpl.class, pk );
454 	    	getCacheAdministrator().putInCache(cacheKey, permissions, PERMISSION_IMPL_CACHE_GROUP);
455     	}
456     	return permissions;
457     }
458 
459     
460     
461     // --------------------
462     // Support Methods
463     // --------------------
464 	
465 	
466 	protected RoleService getRoleService() {
467 		if ( roleService == null ) {
468 			roleService = KIMServiceLocator.getRoleManagementService();
469 		}
470 
471 		return roleService;
472 	}
473 
474 	public void setRoleService(RoleService roleService) {
475 		this.roleService = roleService;
476 	}
477 
478 	public KimPermissionDao getPermissionDao() {
479 		return this.permissionDao;
480 	}
481 
482 	public void setPermissionDao(KimPermissionDao permissionDao) {
483 		this.permissionDao = permissionDao;
484 	}
485 
486 	@SuppressWarnings("unchecked")
487 	public List<KimPermissionInfo> lookupPermissions(Map<String, String> searchCriteria, boolean unbounded ){
488 		Collection baseResults = null;
489 		Lookupable permissionLookupable = KNSServiceLocatorWeb.getLookupable(
490                 KNSServiceLocatorWeb.getBusinessObjectDictionaryService().getLookupableID(PermissionImpl.class)
491         );
492 		permissionLookupable.setBusinessObjectClass(PermissionImpl.class);
493 		if ( unbounded ) {
494 		    baseResults = permissionLookupable.getSearchResultsUnbounded( searchCriteria );
495 		} else {
496 			baseResults = permissionLookupable.getSearchResults(searchCriteria);
497 		}
498 		List<KimPermissionInfo> results = new ArrayList<KimPermissionInfo>( baseResults.size() );
499 		for ( KimPermissionImpl resp : (Collection<PermissionImpl>)baseResults ) {
500 			results.add( resp.toSimpleInfo() );
501 		}
502 		if ( baseResults instanceof CollectionIncomplete ) {
503 			results = new CollectionIncomplete<KimPermissionInfo>( results, ((CollectionIncomplete<KimPermissionInfo>)baseResults).getActualSizeIfTruncated() ); 
504 		}		
505 		return results;
506 	}
507 
508 	public String getPermissionDetailLabel( String permissionId, String kimTypeId, String attributeName) {
509     	// get the type service for this permission
510 		KimPermissionTypeService typeService = getPermissionTypeService(null, null, null, permissionId);
511 		if ( typeService != null ) {
512 			// ask the type service for the attribute definition for the given attribute name
513 			AttributeDefinitionMap attributes = typeService.getAttributeDefinitions( kimTypeId );
514 			String label = null;
515 			for ( AttributeDefinition attributeDef : attributes.values() ) {
516 				if ( attributeDef.getName().equals(attributeName) ) {
517 					label = attributeDef.getLabel();
518 				}
519 			}
520 			// return the attribute label
521 			if ( label != null ) {
522 				return label;
523 			} else {
524 				return "Missing Def: " + attributeName;
525 			}
526 		} else {
527 			return "No Label: " + attributeName;
528 		}
529 	}
530 	
531 	/**
532 	 * @see org.kuali.rice.kim.service.PermissionService#getPermissionTemplate(java.lang.String)
533 	 */
534 	public KimPermissionTemplateInfo getPermissionTemplate(String permissionTemplateId) {
535 		KimPermissionTemplateImpl impl = getBusinessObjectService().findBySinglePrimaryKey( KimPermissionTemplateImpl.class, permissionTemplateId );
536 		if ( impl != null ) {
537 			return impl.toSimpleInfo();
538 		}
539 		return null;
540 	}
541 
542 	/**
543 	 * This overridden method ...
544 	 * 
545 	 * @see org.kuali.rice.kim.service.PermissionService#getPermissionTemplateByName(java.lang.String, java.lang.String)
546 	 */
547 	public KimPermissionTemplateInfo getPermissionTemplateByName(String namespaceCode,
548 			String permissionTemplateName) {
549 		Map<String,String> criteria = new HashMap<String,String>(2);
550 		criteria.put( KimConstants.UniqueKeyConstants.NAMESPACE_CODE, namespaceCode );
551 		criteria.put( KimConstants.UniqueKeyConstants.PERMISSION_TEMPLATE_NAME, permissionTemplateName );
552 		KimPermissionTemplateImpl impl = (KimPermissionTemplateImpl)getBusinessObjectService().findByPrimaryKey( KimPermissionTemplateImpl.class, criteria );
553 		if ( impl != null ) {
554 			return impl.toSimpleInfo();
555 		}
556 		return null;
557 	}
558 	
559 	@SuppressWarnings("unchecked")
560 	public List<KimPermissionTemplateInfo> getAllTemplates() {
561 		if ( allTemplates == null ) {
562 			Map<String,String> criteria = new HashMap<String,String>(1);
563 			criteria.put( KNSPropertyConstants.ACTIVE, "Y" );
564 			List<KimPermissionTemplateImpl> impls = (List<KimPermissionTemplateImpl>)getBusinessObjectService().findMatching( KimPermissionTemplateImpl.class, criteria );
565 			List<KimPermissionTemplateInfo> infos = new ArrayList<KimPermissionTemplateInfo>( impls.size() );
566 			for ( KimPermissionTemplateImpl impl : impls ) {
567 				infos.add( impl.toSimpleInfo() );
568 			}
569 			Collections.sort(infos, new Comparator<KimPermissionTemplateInfo>() {
570 				public int compare(KimPermissionTemplateInfo tmpl1,
571 						KimPermissionTemplateInfo tmpl2) {
572 					int result = 0;
573 					result = tmpl1.getNamespaceCode().compareTo(tmpl2.getNamespaceCode());
574 					if ( result != 0 ) {
575 						return result;
576 					}
577 					result = tmpl1.getName().compareTo(tmpl2.getName());
578 					return result;
579 				}
580 			});
581 			allTemplates = infos;
582 		}
583 		return allTemplates;
584 	}
585 
586     
587 	
588 	private DataDictionaryService dataDictionaryService;
589 	protected DataDictionaryService getDataDictionaryService() {
590 		if(dataDictionaryService == null){
591 			dataDictionaryService = KNSServiceLocatorWeb.getDataDictionaryService();
592 		}
593 		return dataDictionaryService;
594 	}
595 	
596 
597     public List<String> getRoleIdsForPermissionId(String permissionId) {
598         KimPermissionInfo permissionInfo = getPermission(permissionId);
599 
600         List<KimPermissionInfo> applicablePermissions = new ArrayList<KimPermissionInfo>();
601         applicablePermissions.add(permissionInfo);
602 
603         List<String> roleIds = getRolesForPermissionsFromCache(applicablePermissions);
604         if (roleIds == null) {
605             roleIds = permissionDao.getRoleIdsForPermissions(applicablePermissions);
606             addRolesForPermissionsToCache(applicablePermissions, roleIds);
607         }
608 
609         return roleIds;
610     }
611 
612     public List<KimPermissionInfo> getPermissionsByNameIncludingInactive(String namespaceCode, String permissionName) {
613         List<KimPermissionImpl> impls = getPermissionImplsByNameIncludingInactive(namespaceCode, permissionName);
614         List<KimPermissionInfo> results = new ArrayList<KimPermissionInfo>(impls.size());
615         for (KimPermissionImpl impl : impls) {
616             results.add(impl.toSimpleInfo());
617         }
618         return results;
619     }
620 	
621     @SuppressWarnings("unchecked")
622     protected List<KimPermissionImpl> getPermissionImplsByNameIncludingInactive(String namespaceCode, String permissionName) {
623         String cacheKey = getPermissionImplByNameCacheKey(namespaceCode, permissionName + "inactive");
624         List<KimPermissionImpl> permissions = (List<KimPermissionImpl>) getCacheAdministrator().getFromCache(cacheKey);
625         if (permissions == null) {
626             HashMap<String, Object> pk = new HashMap<String, Object>(2);
627             pk.put(KimConstants.UniqueKeyConstants.NAMESPACE_CODE, namespaceCode);
628             pk.put(KimConstants.UniqueKeyConstants.PERMISSION_NAME, permissionName);
629             permissions = (List<KimPermissionImpl>) getBusinessObjectService().findMatching(KimPermissionImpl.class, pk);
630             getCacheAdministrator().putInCache(cacheKey, permissions, PERMISSION_IMPL_CACHE_GROUP);
631         }
632         return permissions;
633     }
634 	
635 }