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.apache.struts.action.ActionMessages;
24 import org.kuali.rice.core.api.config.property.ConfigContext;
25 import org.kuali.rice.core.api.criteria.Predicate;
26 import org.kuali.rice.core.api.criteria.QueryByCriteria;
27 import org.kuali.rice.kew.doctype.bo.DocumentType;
28 import org.kuali.rice.kew.doctype.service.DocumentTypeService;
29 import org.kuali.rice.kew.engine.node.BranchPrototype;
30 import org.kuali.rice.kew.engine.node.RouteNode;
31 import org.kuali.rice.kew.engine.node.RouteNodeConfigParam;
32 import org.kuali.rice.kew.rule.RuleBaseValues;
33 import org.kuali.rice.kew.rule.bo.RuleTemplateBo;
34 import org.kuali.rice.kew.rule.service.RuleServiceInternal;
35 import org.kuali.rice.kew.service.KEWServiceLocator;
36 import org.kuali.rice.kew.api.KewApiConstants;
37 import org.kuali.rice.kew.web.KewKualiAction;
38 import org.kuali.rice.kim.api.KimConstants;
39 import org.kuali.rice.kim.api.group.Group;
40 import org.kuali.rice.kim.api.permission.Permission;
41 import org.kuali.rice.kim.api.responsibility.Responsibility;
42 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
43 import org.kuali.rice.kns.service.DocumentHelperService;
44 import org.kuali.rice.kns.service.KNSServiceLocator;
45 import org.kuali.rice.kns.service.MaintenanceDocumentDictionaryService;
46 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
47 import org.kuali.rice.krad.util.GlobalVariables;
48 import org.kuali.rice.krad.util.KRADConstants;
49
50 import javax.servlet.http.HttpServletRequest;
51 import javax.servlet.http.HttpServletResponse;
52 import java.util.ArrayList;
53 import java.util.Collections;
54 import java.util.Comparator;
55 import java.util.HashMap;
56 import java.util.Iterator;
57 import java.util.List;
58
59 import static org.kuali.rice.core.api.criteria.PredicateFactory.and;
60 import static org.kuali.rice.core.api.criteria.PredicateFactory.equal;
61
62
63
64
65
66
67
68 public class RuleQuickLinksAction extends KewKualiAction {
69
70 private static final Logger LOG = Logger.getLogger(RuleQuickLinksAction.class);
71
72 private MaintenanceDocumentDictionaryService maintenanceDocumentDictionaryService;
73 private DocumentHelperService documentHelperService;
74
75 public ActionForward start(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
76 makeLookupPathParam(mapping, request);
77 establishRequiredState(request, form);
78 return mapping.findForward("basic");
79 }
80
81 @SuppressWarnings("unchecked")
82 public ActionMessages establishRequiredState(HttpServletRequest request, ActionForm form) throws Exception {
83 RuleQuickLinksForm qlForm = (RuleQuickLinksForm) form;
84 List<DocumentType> documentTypes;
85 if (qlForm.getRootDocTypeName() != null) {
86 documentTypes = new ArrayList<DocumentType>();
87 DocumentType docType = getDocumentTypeService().findByName(qlForm.getRootDocTypeName());
88 documentTypes.add(docType);
89 request.setAttribute("renderOpened", Boolean.TRUE);
90 } else {
91 documentTypes = getDocumentTypeService().findAllCurrentRootDocuments();
92 }
93 qlForm.setDocumentTypeQuickLinksStructures(getDocumentTypeDataStructure(documentTypes));
94 int shouldDisplayCount = 0;
95 for ( DocumentTypeQuickLinksStructure dt : qlForm.getDocumentTypeQuickLinksStructures() ) {
96 if ( dt.isShouldDisplay() ) {
97 shouldDisplayCount++;
98 }
99 }
100 if ( shouldDisplayCount == 1 ) {
101 request.setAttribute("renderOpened", Boolean.TRUE);
102 }
103 String documentTypeName = getMaintenanceDocumentDictionaryService().getDocumentTypeName(DocumentType.class);
104 try {
105 if ((documentTypeName != null) && getDocumentHelperService().getDocumentAuthorizer(documentTypeName).canInitiate(documentTypeName, GlobalVariables.getUserSession().getPerson())) {
106 qlForm.setCanInitiateDocumentTypeDocument( true );
107 }
108 } catch (Exception ex) {
109
110 LOG.error( "Unable to check initiation permission for "+ documentTypeName, ex );
111 }
112
113 return null;
114 }
115
116 public ActionForward addDelegationRule(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
117 ActionForward result = null;
118
119 String ruleTemplateId = request.getParameter("delegationRule.ruleTemplate.id");
120 String docTypeName = request.getParameter("delegationRule.documentType.name");
121 List rules = getRuleService().search(docTypeName, null, ruleTemplateId, "", null, null, Boolean.FALSE, Boolean.TRUE, new HashMap(), null);
122
123 if (rules.size() == 1) {
124 RuleBaseValues rule = (RuleBaseValues)rules.get(0);
125 String url = ConfigContext.getCurrentContextConfig().getKEWBaseURL() +
126 "/DelegateRule.do?methodToCall=start" +
127 "&parentRuleId=" + rule.getId();
128 result = new ActionForward(url, true);
129 } else {
130 makeLookupPathParam(mapping, request);
131 result = new ActionForward(ConfigContext.getCurrentContextConfig().getKRBaseURL() +
132 "/lookup.do?methodToCall=start&"+ stripMethodToCall(request.getQueryString()), true);
133 }
134
135 return result;
136 }
137
138 private List getDocumentTypeDataStructure(List rootDocuments) {
139 List documentTypeQuickLinksStructures = new ArrayList();
140 for (Iterator iter = rootDocuments.iterator(); iter.hasNext();) {
141 DocumentTypeQuickLinksStructure quickLinkStruct =new DocumentTypeQuickLinksStructure((DocumentType) iter.next());
142 if (! quickLinkStruct.getFlattenedNodes().isEmpty() || ! quickLinkStruct.getChildrenDocumentTypes().isEmpty()) {
143 documentTypeQuickLinksStructures.add(quickLinkStruct);
144 }
145
146 }
147
148 return documentTypeQuickLinksStructures;
149 }
150
151
152
153
154
155
156
157
158 public static class DocumentTypeQuickLinksStructure {
159 private DocumentType documentType;
160 private List<RouteNode> flattenedNodes = new ArrayList<RouteNode>();
161 private List<DocumentTypeQuickLinksStructure> childrenDocumentTypes = new ArrayList<DocumentTypeQuickLinksStructure>();
162 private List<Permission> permissions = null;
163
164 private DocumentTypeQuickLinksStructure(DocumentType documentType) {
165 this.documentType = documentType;
166 if ( documentType != null ) {
167 List<RouteNode> tempFlattenedNodes = KEWServiceLocator.getRouteNodeService()
168 .getFlattenedNodes( documentType, true );
169 for ( RouteNode routeNode : tempFlattenedNodes ) {
170 if ( routeNode.isFlexRM() || routeNode.isRoleNode() ) {
171 flattenedNodes.add( new RouteNodeForDisplay( routeNode ) );
172 }
173 }
174 Collections.sort(flattenedNodes,new Comparator() {
175 public int compare(Object o1, Object o2) {
176 return ( ((RouteNode)o1).getRouteNodeName().compareTo(((RouteNode)o2).getRouteNodeName()));
177 }
178 });
179 for ( Iterator<DocumentType> iter = documentType.getChildrenDocTypes().iterator(); iter.hasNext(); ) {
180 childrenDocumentTypes.add( new DocumentTypeQuickLinksStructure( iter.next() ) );
181 }
182 Collections.sort(childrenDocumentTypes,new Comparator() {
183 public int compare(Object o1, Object o2) {
184 return ( ((DocumentTypeQuickLinksStructure)o1).documentType.getLabel().compareTo(((DocumentTypeQuickLinksStructure)o2).documentType.getLabel()));
185 }
186 });
187 }
188 }
189
190 public List getChildrenDocumentTypes() {
191 return childrenDocumentTypes;
192 }
193 public void setChildrenDocumentTypes(List<DocumentTypeQuickLinksStructure> childrenDocumentTypes) {
194 this.childrenDocumentTypes = childrenDocumentTypes;
195 }
196 public DocumentType getDocumentType() {
197 return documentType;
198 }
199 public void setDocumentType(DocumentType documentType) {
200 this.documentType = documentType;
201 }
202 public List getFlattenedNodes() {
203 return flattenedNodes;
204 }
205 public void setFlattenedNodes(List<RouteNode> flattenedNodes) {
206 this.flattenedNodes = flattenedNodes;
207 }
208 public boolean isShouldDisplay() {
209
210
211
212
213
214
215
216
217 return true;
218 }
219
220 public List<Permission> getPermissions() {
221 if ( permissions == null ) {
222 Predicate p = and(
223 equal("attributeName", "documentTypeName"),
224 equal("active", "Y"),
225 equal("detailCriteria",
226 KimConstants.AttributeConstants.DOCUMENT_TYPE_NAME+"="+getDocumentType().getName()));
227 permissions = KimApiServiceLocator.getPermissionService().findPermissions( QueryByCriteria.Builder.fromPredicates(p)).getResults();
228
229 }
230 return permissions;
231 }
232
233 public boolean isHasRelatedPermissions() {
234 return !getPermissions().isEmpty();
235 }
236
237 public int getRelatedPermissionCount() {
238 return getPermissions().size();
239 }
240 }
241
242 public static class RouteNodeForDisplay extends RouteNode {
243 private static final long serialVersionUID = 1L;
244 private RouteNode baseNode;
245
246 public RouteNodeForDisplay( RouteNode baseNode ) {
247 this.baseNode = baseNode;
248 }
249
250 public boolean equals(Object obj) {
251 return this.baseNode.equals(obj);
252 }
253
254 public String getActivationType() {
255 return this.baseNode.getActivationType();
256 }
257
258 public BranchPrototype getBranch() {
259 return this.baseNode.getBranch();
260 }
261
262 public List<RouteNodeConfigParam> getConfigParams() {
263 return this.baseNode.getConfigParams();
264 }
265
266 public String getContentFragment() {
267 return this.baseNode.getContentFragment();
268 }
269
270 public DocumentType getDocumentType() {
271 return this.baseNode.getDocumentType();
272 }
273
274 public String getDocumentTypeId() {
275 return this.baseNode.getDocumentTypeId();
276 }
277 public Group getExceptionWorkgroup() {
278 return this.baseNode.getExceptionWorkgroup();
279 }
280 public String getExceptionWorkgroupId() {
281 return this.baseNode.getExceptionWorkgroupId();
282 }
283 public String getExceptionWorkgroupName() {
284 return this.baseNode.getExceptionWorkgroupName();
285 }
286 public Boolean getFinalApprovalInd() {
287 return this.baseNode.getFinalApprovalInd();
288 }
289 public Integer getLockVerNbr() {
290 return this.baseNode.getLockVerNbr();
291 }
292 public Boolean getMandatoryRouteInd() {
293 return this.baseNode.getMandatoryRouteInd();
294 }
295 public List<RouteNode> getNextNodes() {
296 return this.baseNode.getNextNodes();
297 }
298 public String getNodeType() {
299 return this.baseNode.getNodeType();
300 }
301 public List<RouteNode> getPreviousNodes() {
302 return this.baseNode.getPreviousNodes();
303 }
304 public String getRouteMethodCode() {
305 return this.baseNode.getRouteMethodCode();
306 }
307 public String getRouteMethodName() {
308 return this.baseNode.getRouteMethodName();
309 }
310 public String getRouteNodeId() {
311 return this.baseNode.getRouteNodeId();
312 }
313 public String getRouteNodeName() {
314 return this.baseNode.getRouteNodeName();
315 }
316 public RuleTemplateBo getRuleTemplate() {
317 return this.baseNode.getRuleTemplate();
318 }
319 public int hashCode() {
320 return this.baseNode.hashCode();
321 }
322 public boolean isExceptionGroupDefined() {
323 return this.baseNode.isExceptionGroupDefined();
324 }
325 public boolean isFlexRM() {
326 return this.baseNode.isFlexRM();
327 }
328 public boolean isRoleNode() {
329 return this.baseNode.isRoleNode();
330 }
331 public String toString() {
332 return this.baseNode.toString();
333 }
334
335 private List<Responsibility> responsibilities = null;
336
337 public List<Responsibility> getResponsibilities() {
338 if ( responsibilities == null ) {
339 QueryByCriteria.Builder builder = QueryByCriteria.Builder.create();
340 Predicate p = and(
341 equal("template.namespaceCode", KRADConstants.KUALI_RICE_WORKFLOW_NAMESPACE),
342 equal("template.name", KewApiConstants.DEFAULT_RESPONSIBILITY_TEMPLATE_NAME),
343 equal("active", "Y"),
344 equal("attributes[documentTypeName]", getDocumentType().getName())
345
346
347
348 );
349
350
351 builder.setPredicates(p);
352
353 List<Responsibility> possibleResponsibilities =
354 KimApiServiceLocator.getResponsibilityService().findResponsibilities(builder.build()).getResults();
355
356 if ( !possibleResponsibilities.isEmpty() ) {
357 for ( Responsibility resp : possibleResponsibilities ) {
358 String routeNodeName = resp.getAttributes().get( KimConstants.AttributeConstants.ROUTE_NODE_NAME);
359 if (StringUtils.isNotEmpty(routeNodeName) && StringUtils.equals(routeNodeName, getRouteNodeName())){
360 responsibilities.add(resp);
361 }
362 }
363 } else {
364 responsibilities = possibleResponsibilities;
365 }
366 }
367 return responsibilities;
368 }
369
370 public int getResponsibilityCount() {
371 return getResponsibilities().size();
372 }
373
374 public boolean isHasResponsibility() {
375 return !getResponsibilities().isEmpty();
376 }
377 }
378
379 private void makeLookupPathParam(ActionMapping mapping, HttpServletRequest request) {
380 String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + mapping.getModuleConfig().getPrefix();
381 request.setAttribute("basePath", basePath);
382 }
383
384 private String stripMethodToCall(String queryString) {
385 return queryString.replaceAll("methodToCall=addDelegationRule&", "");
386 }
387
388 private DocumentTypeService getDocumentTypeService() {
389 return KEWServiceLocator.getDocumentTypeService();
390 }
391
392 private RuleServiceInternal getRuleService() {
393 return KEWServiceLocator.getRuleService();
394 }
395
396 public DocumentHelperService getDocumentHelperService() {
397 if(documentHelperService == null){
398 documentHelperService = KNSServiceLocator.getDocumentHelperService();
399 }
400 return documentHelperService;
401 }
402
403 public MaintenanceDocumentDictionaryService getMaintenanceDocumentDictionaryService() {
404 if(maintenanceDocumentDictionaryService == null){
405 maintenanceDocumentDictionaryService = KNSServiceLocator.getMaintenanceDocumentDictionaryService();
406 }
407 return maintenanceDocumentDictionaryService;
408 }
409
410 @Override
411 public ActionForward toggleTab(ActionMapping mapping, ActionForm form,
412 HttpServletRequest request, HttpServletResponse response)
413 throws Exception {
414
415 establishRequiredState(request, form);
416 return super.toggleTab(mapping, form, request, response);
417 }
418
419 }