1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kew.rule.web;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.apache.log4j.Logger;
20 import org.apache.struts.action.ActionForm;
21 import org.apache.struts.action.ActionForward;
22 import org.apache.struts.action.ActionMapping;
23 import org.kuali.rice.core.api.criteria.Predicate;
24 import org.kuali.rice.core.api.criteria.QueryByCriteria;
25 import org.kuali.rice.kew.doctype.bo.DocumentType;
26 import org.kuali.rice.kew.doctype.service.DocumentTypeService;
27 import org.kuali.rice.kew.engine.node.ProcessDefinitionBo;
28 import org.kuali.rice.kew.engine.node.RouteNode;
29 import org.kuali.rice.kew.engine.node.service.RouteNodeService;
30 import org.kuali.rice.kew.service.KEWServiceLocator;
31 import org.kuali.rice.kew.api.KewApiConstants;
32 import org.kuali.rice.kew.web.KewKualiAction;
33 import org.kuali.rice.kim.api.KimConstants;
34 import org.kuali.rice.kim.api.permission.Permission;
35 import org.kuali.rice.kim.api.permission.PermissionService;
36 import org.kuali.rice.kim.api.responsibility.Responsibility;
37 import org.kuali.rice.kim.api.responsibility.ResponsibilityService;
38 import org.kuali.rice.kim.api.role.Role;
39 import org.kuali.rice.kim.api.role.RoleService;
40 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
41 import org.kuali.rice.kim.bo.impl.KimAttributes;
42 import org.kuali.rice.kim.impl.permission.GenericPermissionBo;
43 import org.kuali.rice.kim.impl.permission.PermissionBo;
44 import org.kuali.rice.kim.impl.permission.PermissionTemplateBo;
45 import org.kuali.rice.kim.impl.responsibility.ReviewResponsibilityBo;
46 import org.kuali.rice.kns.service.DocumentHelperService;
47 import org.kuali.rice.kns.service.KNSServiceLocator;
48 import org.kuali.rice.kns.service.MaintenanceDocumentDictionaryService;
49 import org.kuali.rice.krad.service.DataDictionaryService;
50 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
51 import org.kuali.rice.krad.util.GlobalVariables;
52 import org.kuali.rice.krad.util.KRADConstants;
53
54 import javax.servlet.http.HttpServletRequest;
55 import javax.servlet.http.HttpServletResponse;
56 import java.util.ArrayList;
57 import java.util.Collections;
58 import java.util.HashMap;
59 import java.util.HashSet;
60 import java.util.LinkedHashMap;
61 import java.util.List;
62 import java.util.Map;
63 import java.util.Set;
64
65 import static org.kuali.rice.core.api.criteria.PredicateFactory.*;
66
67
68
69
70
71
72
73
74 public class DocumentConfigurationViewAction extends KewKualiAction {
75
76 private static final Logger LOG = Logger.getLogger(DocumentConfigurationViewAction.class);
77
78 private PermissionService permissionService;
79 private RoleService roleService;
80 private ResponsibilityService responsibilityService;
81 private DocumentTypeService documentTypeService;
82 private DataDictionaryService dataDictionaryService;
83 private RouteNodeService routeNodeService;
84 private MaintenanceDocumentDictionaryService maintenanceDocumentDictionaryService;
85 private DocumentHelperService documentHelperService;
86
87 public ActionForward start(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
88 populateForm( (DocumentConfigurationViewForm)form );
89 return mapping.findForward("basic");
90 }
91
92 protected void populateForm( DocumentConfigurationViewForm form ) {
93 if ( StringUtils.isNotEmpty( form.getDocumentTypeName() ) ) {
94 form.setDocumentType( getDocumentTypeService().findByName( form.getDocumentTypeName() ) );
95 if ( form.getDocumentType() != null ) {
96 form.getDocumentType().getChildrenDocTypes();
97 form.setAttributeLabels( new HashMap<String, String>() );
98 populateRelatedDocuments( form );
99 populatePermissions( form );
100 populateRoutingResponsibilities( form );
101 populateRoutingExceptionResponsibility( form );
102 checkPermissions( form );
103 }
104 }
105 }
106
107 protected void checkPermissions( DocumentConfigurationViewForm form ) {
108 String docTypeDocumentType = getMaintenanceDocumentDictionaryService().getDocumentTypeName(DocumentType.class);
109 try {
110 if ((docTypeDocumentType != null) && getDocumentHelperService().getDocumentAuthorizer(docTypeDocumentType).canInitiate(docTypeDocumentType, GlobalVariables.getUserSession().getPerson())) {
111 form.setCanInitiateDocumentTypeDocument( true );
112 }
113 } catch (Exception ex) {
114
115 LOG.error( "Unable to check DocumentType initiation permission for "+ docTypeDocumentType, ex );
116 }
117 String permissionDocumentType = getMaintenanceDocumentDictionaryService().getDocumentTypeName(GenericPermissionBo.class);
118 try {
119 if ((permissionDocumentType != null) && getDocumentHelperService().getDocumentAuthorizer(permissionDocumentType).canInitiate(permissionDocumentType, GlobalVariables.getUserSession().getPerson())) {
120 form.setCanInitiatePermissionDocument( true );
121 }
122 } catch (Exception ex) {
123
124 LOG.error( "Unable to check Permission initiation permission for "+ permissionDocumentType, ex );
125 }
126 String responsibilityDocumentType = getMaintenanceDocumentDictionaryService().getDocumentTypeName(ReviewResponsibilityBo.class);
127 try {
128 if ((responsibilityDocumentType != null) && getDocumentHelperService().getDocumentAuthorizer(responsibilityDocumentType).canInitiate(responsibilityDocumentType, GlobalVariables.getUserSession().getPerson())) {
129 form.setCanInitiateResponsibilityDocument( true );
130 }
131 } catch (Exception ex) {
132
133 LOG.error( "Unable to check Responsibility initiation permission for "+ responsibilityDocumentType, ex );
134 }
135 }
136
137 @SuppressWarnings("unchecked")
138 public void populateRelatedDocuments( DocumentConfigurationViewForm form ) {
139 form.setParentDocumentType( form.getDocumentType().getParentDocType() );
140 form.setChildDocumentTypes( new ArrayList<DocumentType>( form.getDocumentType().getChildrenDocTypes() ) );
141 }
142
143 public void populatePermissions( DocumentConfigurationViewForm form ) {
144
145 DocumentType docType = form.getDocumentType();
146 Map<String,List<Role>> permRoles = new HashMap<String, List<Role>>();
147
148 Set<String> seenDocumentPermissions = new HashSet<String>();
149 while ( docType != null) {
150 String documentTypeName = docType.getName();
151 Predicate p = and(
152 equal("active", Boolean.TRUE),
153 equal("attributes[" + KimConstants.AttributeConstants.DOCUMENT_TYPE_NAME + "]", docType.getName()));
154 List<Permission> perms = getPermissionService().findPermissions(QueryByCriteria.Builder.fromPredicates(p)).getResults();
155 for ( Permission perm : perms ) {
156 PermissionBo permBo = PermissionBo.from(perm);
157 List<String> roleIds = getPermissionService().getRoleIdsForPermission(perm.getNamespaceCode(),
158 perm.getName());
159 if (!roleIds.isEmpty()) {
160 permRoles.put( perm.getId(), getRoleService().getRoles(roleIds) );
161 }
162 for ( String attributeName : permBo.getDetails().keySet() ) {
163 addAttributeLabel(form, attributeName);
164 }
165 }
166
167 if ( perms.size() > 0 || documentTypeName.equals( form.getDocumentTypeName() ) ) {
168 ArrayList<PermissionForDisplay> dispPerms = new ArrayList<PermissionForDisplay>( perms.size() );
169 for ( Permission perm : perms ) {
170 PermissionBo permBo = PermissionBo.from(perm);
171 if ( permBo.getDetails().size() == 1 ) {
172
173 if ( seenDocumentPermissions.contains(perm.getTemplate().getNamespaceCode()+"|"+perm.getTemplate().getName()) ) {
174 dispPerms.add( new PermissionForDisplay( permBo, true ) );
175 } else {
176 dispPerms.add( new PermissionForDisplay( permBo, false ) );
177 seenDocumentPermissions.add(perm.getTemplate().getNamespaceCode()+"|"+perm.getTemplate().getName());
178 }
179 } else {
180
181 dispPerms.add( new PermissionForDisplay( permBo, false ) );
182 }
183 }
184 form.setPermissionsForDocumentType(documentTypeName, dispPerms );
185 form.addDocumentType(documentTypeName);
186 }
187 docType = docType.getParentDocType();
188 }
189
190 form.setPermissionRoles( permRoles );
191 }
192
193 protected void populateRoutingExceptionResponsibility( DocumentConfigurationViewForm form ) {
194 DocumentType docType = form.getDocumentType();
195 List<ResponsibilityForDisplay> responsibilities = new ArrayList<ResponsibilityForDisplay>();
196 while ( docType != null) {
197 QueryByCriteria.Builder builder = QueryByCriteria.Builder.create();
198 Predicate p = and(
199 equal("template.namespaceCode", KRADConstants.KUALI_RICE_WORKFLOW_NAMESPACE),
200 equal("template.name", KewApiConstants.EXCEPTION_ROUTING_RESPONSIBILITY_TEMPLATE_NAME),
201 equal("active", Boolean.TRUE),
202 equal("attributes[documentTypeName]", docType.getName())
203 );
204 builder.setPredicates(p);
205 List<Responsibility> resps = getResponsibilityService().findResponsibilities(builder.build()).getResults();
206
207 for ( Responsibility r : resps ) {
208 if ( responsibilities.isEmpty() ) {
209 responsibilities.add( new ResponsibilityForDisplay( r, false ) );
210 } else {
211 responsibilities.add( new ResponsibilityForDisplay( r, true ) );
212 }
213 }
214 docType = docType.getParentDocType();
215 }
216 form.setExceptionResponsibilities( responsibilities );
217 for ( ResponsibilityForDisplay responsibility : responsibilities ) {
218 List<String> roleIds = getResponsibilityService().getRoleIdsForResponsibility(responsibility.getResp().getId());
219 if (!roleIds.isEmpty()) {
220 form.getResponsibilityRoles().put( responsibility.getResponsibilityId(), getRoleService().getRoles(roleIds) );
221 }
222 }
223 }
224
225 protected void addAttributeLabel( DocumentConfigurationViewForm form, String attributeName ) {
226 if ( !form.getAttributeLabels().containsKey(attributeName) ) {
227 form.getAttributeLabels().put(attributeName,
228 getDataDictionaryService().getAttributeLabel(KimAttributes.class, attributeName) );
229 }
230 }
231
232
233
234
235
236
237
238 protected RouteNode flattenSplitNode( RouteNode splitNode, Map<String,RouteNode> nodes ) {
239 nodes.put( splitNode.getRouteNodeName(), splitNode );
240 RouteNode joinNode = null;
241
242 for ( RouteNode nextNode : splitNode.getNextNodes() ) {
243 joinNode = flattenRouteNodes(nextNode, nodes);
244 }
245
246 if ( joinNode != null ) {
247 nodes.put( joinNode.getRouteNodeName(), joinNode );
248 }
249 return joinNode;
250 }
251
252
253
254
255
256
257 protected RouteNode flattenRouteNodes( RouteNode node, Map<String,RouteNode> nodes ) {
258 RouteNode lastProcessedNode = null;
259 if (node != null) {
260
261 if ( nodes.containsKey(node.getRouteNodeName()) ) {
262 return node;
263 }
264
265 if ( node.getNodeType().contains( "SplitNode" ) ) {
266 lastProcessedNode = flattenSplitNode(node, nodes);
267
268 if (lastProcessedNode != null) {
269 for ( RouteNode nextNode : lastProcessedNode.getNextNodes() ) {
270 lastProcessedNode = flattenRouteNodes(nextNode, nodes);
271 }
272 }
273 } else if ( node.getNodeType().contains( "JoinNode" ) ) {
274 lastProcessedNode = node;
275 } else {
276
277 nodes.put(node.getRouteNodeName(), node);
278 for ( RouteNode nextNode : node.getNextNodes() ) {
279 lastProcessedNode = flattenRouteNodes(nextNode, nodes);
280 }
281 }
282 }
283 return lastProcessedNode;
284 }
285
286 @SuppressWarnings("unchecked")
287 public void populateRoutingResponsibilities( DocumentConfigurationViewForm form ) {
288
289
290
291
292 Map<String,List<Role>> respToRoleMap = new HashMap<String, List<Role>>();
293 List<ProcessDefinitionBo> processes = (List<ProcessDefinitionBo>)form.getDocumentType().getProcesses();
294 if (!(processes.isEmpty())) {
295 RouteNode rootNode = processes.get(0).getInitialRouteNode();
296 LinkedHashMap<String, RouteNode> routeNodeMap = new LinkedHashMap<String, RouteNode>();
297 flattenRouteNodes(rootNode, routeNodeMap);
298
299 form.setRouteNodes( new ArrayList<RouteNode>( routeNodeMap.values() ) );
300
301
302
303
304 DocumentType docType = form.getDocumentType();
305 Set<Responsibility> responsibilities = new HashSet<Responsibility>();
306 Map<String,List<ResponsibilityForDisplay>> nodeToRespMap = new LinkedHashMap<String, List<ResponsibilityForDisplay>>();
307 while ( docType != null) {
308 QueryByCriteria.Builder builder = QueryByCriteria.Builder.create();
309 Predicate p = and(
310 equal("template.namespaceCode", KRADConstants.KUALI_RICE_WORKFLOW_NAMESPACE),
311 equal("template.name", KewApiConstants.DEFAULT_RESPONSIBILITY_TEMPLATE_NAME),
312 equal("active", Boolean.TRUE),
313 equal("attributes[documentTypeName]", docType.getName())
314 );
315 builder.setPredicates(p);
316 List<Responsibility> resps = getResponsibilityService().findResponsibilities(builder.build()).getResults();
317
318 for ( Responsibility r : resps ) {
319 String routeNodeName = r.getAttributes().get(KimConstants.AttributeConstants.ROUTE_NODE_NAME);
320 if ( StringUtils.isNotBlank(routeNodeName) ) {
321 if ( !nodeToRespMap.containsKey( routeNodeName ) ) {
322 nodeToRespMap.put(routeNodeName, new ArrayList<ResponsibilityForDisplay>() );
323 nodeToRespMap.get(routeNodeName).add( new ResponsibilityForDisplay( r, false ) );
324 } else {
325
326
327
328 if ( nodeToRespMap.get(routeNodeName).get(0).getDetails().get( KimConstants.AttributeConstants.DOCUMENT_TYPE_NAME ).equals(docType.getName() ) ) {
329 nodeToRespMap.get(routeNodeName).add( new ResponsibilityForDisplay( r, false ) );
330 } else {
331 nodeToRespMap.get(routeNodeName).add( new ResponsibilityForDisplay( r, true ) );
332 }
333 }
334 responsibilities.add(r);
335 }
336 }
337 docType = docType.getParentDocType();
338 }
339 form.setResponsibilityMap( nodeToRespMap );
340
341 for (Responsibility responsibility : responsibilities ) {
342 List<String> roleIds = getResponsibilityService().getRoleIdsForResponsibility(responsibility.getId());
343 if (!roleIds.isEmpty()) {
344 respToRoleMap.put( responsibility.getId(), getRoleService().getRoles(roleIds) );
345 }
346 }
347 }
348 form.setResponsibilityRoles( respToRoleMap );
349 }
350
351 @Override
352 public ActionForward toggleTab(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
353
354 ActionForward actionForward = super.toggleTab(mapping, form, request, response);
355 populateForm( (DocumentConfigurationViewForm)form );
356 return actionForward;
357 }
358
359
360
361
362 public static class ResponsibilityForDisplay {
363
364 private Responsibility resp;
365 private boolean overridden = false;
366
367 public ResponsibilityForDisplay( Responsibility resp, boolean overridden ) {
368 this.resp = resp;
369 this.overridden = overridden;
370 }
371
372
373
374
375 Responsibility getResp() {
376 return this.resp;
377 }
378
379 public boolean isOverridden() {
380 return this.overridden;
381 }
382
383 public void setOverridden(boolean overridden) {
384 this.overridden = overridden;
385 }
386
387 public Map<String, String> getDetails() {
388 return new HashMap<String, String>(this.resp.getAttributes());
389 }
390
391 public String getName() {
392 return this.resp.getName();
393 }
394
395 public String getNamespaceCode() {
396 return this.resp.getNamespaceCode();
397 }
398
399 public String getResponsibilityId() {
400 return this.resp.getId();
401 }
402 }
403
404 public static class PermissionForDisplay {
405 private PermissionBo perm;
406 private boolean overridden = false;
407
408 public PermissionForDisplay( PermissionBo perm, boolean overridden ) {
409 this.perm = perm;
410 this.overridden = overridden;
411 }
412 public boolean isOverridden() {
413 return this.overridden;
414 }
415
416 public void setOverridden(boolean overridden) {
417 this.overridden = overridden;
418 }
419 public Map<String, String> getDetails() {
420 return this.perm.getDetails();
421 }
422 public String getName() {
423 return this.perm.getName();
424 }
425 public String getNamespaceCode() {
426 return this.perm.getNamespaceCode();
427 }
428 public String getId() {
429 return this.perm.getId();
430 }
431 public PermissionTemplateBo getTemplate() {
432 return this.perm.getTemplate();
433 }
434
435 }
436
437
438
439
440 public PermissionService getPermissionService() {
441 if ( permissionService == null ) {
442 permissionService = KimApiServiceLocator.getPermissionService();
443 }
444 return permissionService;
445 }
446
447
448
449
450 public RoleService getRoleService() {
451 if ( roleService == null ) {
452 roleService = KimApiServiceLocator.getRoleService();
453 }
454 return roleService;
455 }
456
457
458
459
460 public ResponsibilityService getResponsibilityService() {
461 if ( responsibilityService == null ) {
462 responsibilityService = KimApiServiceLocator.getResponsibilityService();
463 }
464 return responsibilityService;
465 }
466
467
468
469
470 public DocumentTypeService getDocumentTypeService() {
471 if ( documentTypeService == null ) {
472 documentTypeService = KEWServiceLocator.getDocumentTypeService();
473 }
474 return documentTypeService;
475 }
476
477 public DataDictionaryService getDataDictionaryService() {
478 if(dataDictionaryService == null){
479 dataDictionaryService = KRADServiceLocatorWeb.getDataDictionaryService();
480 }
481 return dataDictionaryService;
482 }
483
484 public RouteNodeService getRouteNodeService() {
485 if ( routeNodeService == null ) {
486 routeNodeService = KEWServiceLocator.getRouteNodeService();
487 }
488 return routeNodeService;
489 }
490
491 public DocumentHelperService getDocumentHelperService() {
492 if(documentHelperService == null){
493 documentHelperService = KNSServiceLocator.getDocumentHelperService();
494 }
495 return documentHelperService;
496 }
497
498 public MaintenanceDocumentDictionaryService getMaintenanceDocumentDictionaryService() {
499 if(maintenanceDocumentDictionaryService == null){
500 maintenanceDocumentDictionaryService = KNSServiceLocator.getMaintenanceDocumentDictionaryService();
501 }
502 return maintenanceDocumentDictionaryService;
503 }
504
505 }