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