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