1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kim.lookup;
17
18 import org.apache.commons.beanutils.PropertyUtils;
19 import org.apache.commons.lang.StringUtils;
20 import org.kuali.rice.core.api.membership.MemberType;
21 import org.kuali.rice.kim.api.KimConstants;
22 import org.kuali.rice.kim.api.role.RoleService;
23 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
24 import org.kuali.rice.kim.impl.permission.GenericPermissionBo;
25 import org.kuali.rice.kim.impl.permission.PermissionBo;
26 import org.kuali.rice.kim.impl.permission.UberPermissionBo;
27 import org.kuali.rice.kim.impl.role.RoleBo;
28 import org.kuali.rice.kim.impl.role.RolePermissionBo;
29 import org.kuali.rice.kns.lookup.HtmlData;
30 import org.kuali.rice.krad.bo.BusinessObject;
31 import org.kuali.rice.krad.data.KradDataServiceLocator;
32 import org.kuali.rice.krad.lookup.CollectionIncomplete;
33 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
34 import org.kuali.rice.krad.service.LookupService;
35 import org.kuali.rice.krad.util.KRADConstants;
36 import org.kuali.rice.krad.util.UrlFactory;
37
38 import java.lang.reflect.InvocationTargetException;
39 import java.util.ArrayList;
40 import java.util.HashMap;
41 import java.util.List;
42 import java.util.Map;
43 import java.util.Properties;
44
45 public class PermissionLookupableHelperServiceImpl extends RoleMemberLookupableHelperServiceImpl {
46
47 private static final long serialVersionUID = -3578448525862270477L;
48
49 private transient LookupService lookupService;
50 private transient RoleService roleService;
51 private volatile String genericPermissionDocumentTypeName;
52
53 @Override
54 public List<HtmlData> getCustomActionUrls(BusinessObject businessObject, List pkNames) {
55 List<HtmlData> htmlDataList = new ArrayList<HtmlData>();
56
57 businessObject = new GenericPermissionBo((UberPermissionBo)businessObject);
58 if (allowsMaintenanceEditAction(businessObject)) {
59 htmlDataList.add(getUrlData(businessObject, KRADConstants.MAINTENANCE_EDIT_METHOD_TO_CALL, pkNames));
60 }
61 if (allowsMaintenanceNewOrCopyAction()) {
62 htmlDataList.add(getUrlData(businessObject, KRADConstants.MAINTENANCE_COPY_METHOD_TO_CALL, pkNames));
63 }
64 return htmlDataList;
65 }
66
67 protected String getActionUrlHref(BusinessObject businessObject, String methodToCall, List pkNames){
68 Properties parameters = new Properties();
69 parameters.put(KRADConstants.DISPATCH_REQUEST_PARAMETER, methodToCall);
70 parameters.put(KRADConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE, businessObject.getClass().getName());
71 parameters.put(KRADConstants.OVERRIDE_KEYS, KimConstants.PrimaryKeyConstants.PERMISSION_ID);
72 parameters.put(KRADConstants.COPY_KEYS, KimConstants.PrimaryKeyConstants.PERMISSION_ID);
73 if (StringUtils.isNotBlank(getReturnLocation())) {
74 parameters.put(KRADConstants.RETURN_LOCATION_PARAMETER, getReturnLocation());
75 }
76 parameters.putAll(getParametersFromPrimaryKey(businessObject, pkNames));
77 return UrlFactory.parameterizeUrl(KRADConstants.MAINTENANCE_ACTION, parameters);
78 }
79
80 @Override
81 protected String getMaintenanceDocumentTypeName() {
82
83
84 String g = genericPermissionDocumentTypeName;
85 if (g == null) {
86 synchronized (this) {
87 g = genericPermissionDocumentTypeName;
88 if (g == null) {
89 genericPermissionDocumentTypeName = g = getMaintenanceDocumentDictionaryService().getDocumentTypeName(
90 GenericPermissionBo.class);
91 }
92 }
93 }
94
95 return g;
96 }
97
98 @Override
99 protected List<? extends BusinessObject> getMemberSearchResults(Map<String, String> searchCriteria, boolean unbounded) {
100 Map<String, String> permissionSearchCriteria = buildSearchCriteria(searchCriteria);
101 Map<String, String> roleSearchCriteria = buildRoleSearchCriteria(searchCriteria);
102 boolean permissionCriteriaEmpty = permissionSearchCriteria==null || permissionSearchCriteria.isEmpty();
103 boolean roleCriteriaEmpty = roleSearchCriteria==null || roleSearchCriteria.isEmpty();
104
105 List<UberPermissionBo> permissionSearchResultsCopy = new CollectionIncomplete<UberPermissionBo>(new ArrayList<UberPermissionBo>(), new Long(0));
106 if(!permissionCriteriaEmpty && !roleCriteriaEmpty){
107 permissionSearchResultsCopy = getCombinedSearchResults(permissionSearchCriteria, roleSearchCriteria, unbounded);
108 } else if(permissionCriteriaEmpty && !roleCriteriaEmpty){
109 permissionSearchResultsCopy = getPermissionsWithRoleSearchCriteria(roleSearchCriteria, unbounded);
110 } else if(!permissionCriteriaEmpty && roleCriteriaEmpty){
111 permissionSearchResultsCopy = getPermissionsWithPermissionSearchCriteria(permissionSearchCriteria, unbounded);
112 } else if(permissionCriteriaEmpty && roleCriteriaEmpty){
113 return getAllPermissions(unbounded);
114 }
115 return permissionSearchResultsCopy;
116 }
117
118 private List<UberPermissionBo> getAllPermissions(boolean unbounded){
119 List<UberPermissionBo> permissions = searchPermissions(new HashMap<String, String>(), unbounded);
120 for(UberPermissionBo permission: permissions) {
121 populateAssignedToRoles(permission);
122 }
123 return permissions;
124 }
125
126 private List<UberPermissionBo> getCombinedSearchResults(
127 Map<String, String> permissionSearchCriteria, Map<String, String> roleSearchCriteria, boolean unbounded){
128 List<UberPermissionBo> permissionSearchResults = searchPermissions(permissionSearchCriteria, unbounded);
129 List<RoleBo> roleSearchResults = searchRoles(roleSearchCriteria, unbounded);
130 List<UberPermissionBo> permissionsForRoleSearchResults = getPermissionsForRoleSearchResults(roleSearchResults, unbounded);
131 List<UberPermissionBo> matchedPermissions = new CollectionIncomplete<UberPermissionBo>(
132 new ArrayList<UberPermissionBo>(), getActualSizeIfTruncated(permissionsForRoleSearchResults));
133 if((permissionSearchResults!=null && !permissionSearchResults.isEmpty()) &&
134 (permissionsForRoleSearchResults!=null && !permissionsForRoleSearchResults.isEmpty())){
135 for(UberPermissionBo permission: permissionSearchResults){
136 for(UberPermissionBo permissionFromRoleSearch: permissionsForRoleSearchResults){
137 if(permissionFromRoleSearch.getId().equals(permission.getId())) {
138 matchedPermissions.add(permissionFromRoleSearch);
139 }
140 }
141 }
142 }
143 return matchedPermissions;
144 }
145
146 private List<UberPermissionBo> searchPermissions(Map<String, String> permissionSearchCriteria, boolean unbounded){
147 return getPermissionsSearchResultsCopy(new ArrayList<PermissionBo>(getLookupService().findCollectionBySearchHelper(
148 PermissionBo.class, permissionSearchCriteria, unbounded)));
149
150 }
151
152 private List<UberPermissionBo> getPermissionsWithRoleSearchCriteria(Map<String, String> roleSearchCriteria, boolean unbounded){
153 return getPermissionsForRoleSearchResults(searchRoles(roleSearchCriteria, unbounded), unbounded);
154 }
155
156 private List<UberPermissionBo> getPermissionsForRoleSearchResults(List<RoleBo> roleSearchResults, boolean unbounded){
157 Long actualSizeIfTruncated = getActualSizeIfTruncated(roleSearchResults);
158 List<UberPermissionBo> permissions = new ArrayList<UberPermissionBo>();
159 List<UberPermissionBo> tempPermissions;
160 List<String> collectedPermissionIds = new ArrayList<String>();
161 Map<String, String> permissionCriteria;
162
163 for(RoleBo roleImpl: roleSearchResults){
164 permissionCriteria = new HashMap<String, String>();
165 permissionCriteria.put("rolePermissions.roleId", roleImpl.getId());
166 tempPermissions = searchPermissions(permissionCriteria, unbounded);
167 actualSizeIfTruncated += getActualSizeIfTruncated(tempPermissions);
168 for(UberPermissionBo permission: tempPermissions){
169 if(!collectedPermissionIds.contains(permission.getId())){
170 populateAssignedToRoles(permission);
171 collectedPermissionIds.add(permission.getId());
172 permissions.add(permission);
173 }
174 }
175
176 List<String> parentRoleIds = KimApiServiceLocator.getRoleService().getMemberParentRoleIds(MemberType.ROLE.getCode(), roleImpl.getId());
177 for (String parentRoleId : parentRoleIds) {
178 Map<String, String> roleSearchCriteria = new HashMap<String, String>();
179 roleSearchCriteria.put("id", parentRoleId);
180
181 permissions = mergePermissionLists(permissions, getPermissionsWithRoleSearchCriteria(roleSearchCriteria, unbounded));
182 }
183 }
184
185 return new CollectionIncomplete<UberPermissionBo>(permissions, actualSizeIfTruncated);
186 }
187
188
189 private void populateAssignedToRoles(UberPermissionBo permission){
190 for(RolePermissionBo rolePermission: permission.getRolePermissions()){
191 if ( rolePermission.isActive() ) {
192 RoleBo roleBo = KradDataServiceLocator.getDataObjectService().find(RoleBo.class, rolePermission.getRoleId());
193 if ( roleBo != null ) {
194 permission.getAssignedToRoles().add(roleBo);
195 }
196 }
197 }
198 }
199
200 private List<UberPermissionBo> getPermissionsWithPermissionSearchCriteria(
201 Map<String, String> permissionSearchCriteria, boolean unbounded){
202 String detailCriteriaStr = permissionSearchCriteria.remove( DETAIL_CRITERIA );
203 Map<String, String> detailCriteria = parseDetailCriteria(detailCriteriaStr);
204
205 final List<UberPermissionBo> permissions = searchPermissions(permissionSearchCriteria, unbounded);
206 List<UberPermissionBo> filteredPermissions = new CollectionIncomplete<UberPermissionBo>(
207 new ArrayList<UberPermissionBo>(), getActualSizeIfTruncated(permissions));
208 for(UberPermissionBo perm: permissions){
209 if ( detailCriteria.isEmpty() ) {
210 filteredPermissions.add(perm);
211 populateAssignedToRoles(perm);
212 } else {
213 if ( isMapSubset( new HashMap<String, String>(perm.getDetails()), detailCriteria ) ) {
214 filteredPermissions.add(perm);
215 populateAssignedToRoles(perm);
216 }
217 }
218 }
219 return filteredPermissions;
220 }
221
222 private List<UberPermissionBo> getPermissionsSearchResultsCopy(List<PermissionBo> permissionSearchResults){
223 List<UberPermissionBo> permissionSearchResultsCopy = new CollectionIncomplete<UberPermissionBo>(
224 new ArrayList<UberPermissionBo>(), getActualSizeIfTruncated(permissionSearchResults));
225 for(PermissionBo permissionBo: permissionSearchResults){
226 UberPermissionBo permissionCopy = new UberPermissionBo();
227
228 try {
229 PropertyUtils.copyProperties(permissionCopy, permissionBo);
230
231 permissionCopy.setTemplate(permissionBo.getTemplate());
232 } catch (IllegalAccessException e) {
233 throw new RuntimeException("unable to copy properties");
234 } catch (InvocationTargetException e) {
235 throw new RuntimeException("unable to copy properties");
236 } catch (NoSuchMethodException e) {
237 throw new RuntimeException("unable to copy properties");
238 }
239
240 permissionSearchResultsCopy.add(permissionCopy);
241 }
242 return permissionSearchResultsCopy;
243 }
244
245
246
247
248 public synchronized LookupService getLookupService() {
249 if ( lookupService == null ) {
250 lookupService = KRADServiceLocatorWeb.getLookupService();
251 }
252 return lookupService;
253 }
254
255 public synchronized RoleService getRoleService() {
256 if (roleService == null) {
257 roleService = KimApiServiceLocator.getRoleService();
258 }
259 return roleService;
260 }
261
262 private List<UberPermissionBo> mergePermissionLists(List<UberPermissionBo> perm1, List<UberPermissionBo> perm2) {
263 List<UberPermissionBo> returnList = new ArrayList<UberPermissionBo>(perm1);
264 List<String> permissionIds = new ArrayList<String>(perm1.size());
265 for (UberPermissionBo perm : returnList) {
266 permissionIds.add(perm.getId());
267 }
268 for (int i=0; i<perm2.size(); i++) {
269 if (!permissionIds.contains(perm2.get(i).getId())) {
270 returnList.add(perm2.get(i));
271 }
272 }
273 return returnList;
274 }
275 }