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