001 /** 002 * Copyright 2005-2013 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.kuali.rice.kew.rule.web; 017 018 import org.apache.commons.beanutils.PropertyUtils; 019 import org.apache.commons.lang.ClassUtils; 020 import org.kuali.rice.core.api.delegation.DelegationType; 021 import org.kuali.rice.coreservice.framework.CoreFrameworkServiceLocator; 022 import org.kuali.rice.kew.api.KewApiConstants; 023 import org.kuali.rice.kew.api.action.ActionRequestPolicy; 024 import org.kuali.rice.kew.rule.RuleBaseValues; 025 import org.kuali.rice.kew.rule.RuleDelegationBo; 026 import org.kuali.rice.kew.rule.RuleExtensionBo; 027 import org.kuali.rice.kew.rule.RuleExtensionValue; 028 import org.kuali.rice.kew.rule.RuleResponsibilityBo; 029 import org.kuali.rice.kew.rule.service.RuleServiceInternal; 030 import org.kuali.rice.kew.service.KEWServiceLocator; 031 import org.kuali.rice.kim.api.group.Group; 032 import org.kuali.rice.kim.api.identity.principal.Principal; 033 import org.kuali.rice.kim.api.services.KimApiServiceLocator; 034 import org.kuali.rice.krad.util.KRADConstants; 035 036 import java.lang.reflect.InvocationHandler; 037 import java.lang.reflect.Method; 038 import java.lang.reflect.Proxy; 039 import java.util.Iterator; 040 import java.util.List; 041 042 043 /** 044 * A decorator around a {@link org.kuali.rice.kew.rule.RuleResponsibilityBo} object which provides some 045 * convienance functions for interacting with the bean from the web-tier. 046 * This helps to alleviate some of the weaknesses of JSTL. 047 * 048 * @author Kuali Rice Team (rice.collab@kuali.org) 049 */ 050 public class WebRuleResponsibility extends RuleResponsibilityBo { 051 052 private static final long serialVersionUID = -8422695726158274189L; 053 054 private static final String DISPLAY_INLINE = "display:inline"; 055 056 private static final String DISPLAY_NONE = "display:none"; 057 058 private String reviewer; 059 060 private String reviewerStyle = ""; 061 062 private String personLookupStyle = ""; 063 064 private String workgroupLookupStyle = ""; 065 066 private String roleReviewer; 067 068 private String roleAreaStyle = ""; 069 070 private boolean delegationRulesMaterialized = false; 071 072 private boolean showDelegations = false; 073 074 private int numberOfDelegations; 075 076 private int index = 0; 077 078 private boolean hasDelegateRuleTemplate = false; 079 080 /** 081 * "reviewerId added to support links to workgroup report or user report 082 */ 083 084 private String reviewerId; 085 086 public String getReviewerId() { 087 return reviewerId; 088 } 089 090 public void setReviewerId(String reviewerId) { 091 this.reviewerId = reviewerId; 092 } 093 094 public WebRuleResponsibility() { 095 setRuleResponsibilityType(KewApiConstants.RULE_RESPONSIBILITY_WORKFLOW_ID); 096 setApprovePolicy(ActionRequestPolicy.FIRST.getCode()); 097 } 098 099 public void initialize() throws Exception { 100 if (getDelegationRules().size() <= Integer.parseInt(CoreFrameworkServiceLocator.getParameterService().getParameterValueAsString(KewApiConstants.KEW_NAMESPACE, KRADConstants.DetailTypes.RULE_DETAIL_TYPE, KewApiConstants.RULE_DELEGATE_LIMIT))) { 101 showDelegations = true; 102 } 103 setNumberOfDelegations(getDelegationRules().size()); 104 if (delegationRulesMaterialized) { 105 for (Iterator iterator = getDelegationRules().iterator(); iterator.hasNext();) { 106 RuleDelegationBo ruleDelegation = (RuleDelegationBo) iterator.next(); 107 WebRuleBaseValues webRule = (WebRuleBaseValues) ruleDelegation.getDelegationRule(); 108 webRule.initialize(); 109 } 110 } 111 establishRequiredState(); 112 } 113 114 private void loadWebValues() throws Exception { 115 if (!org.apache.commons.lang.StringUtils.isEmpty(getRuleResponsibilityName())) { 116 if (KewApiConstants.RULE_RESPONSIBILITY_WORKFLOW_ID.equals(getRuleResponsibilityType())) { 117 // setReviewer(getUserService().getWorkflowUser(new 118 // WorkflowUserId(getRuleResponsibilityName())).getPrincipalName().getAuthenticationId()); 119 Principal principal = KEWServiceLocator.getIdentityHelperService().getPrincipal(getRuleResponsibilityName()); 120 setReviewer(principal.getPrincipalName()); 121 setReviewerId(principal.getPrincipalId()); 122 } else if (KewApiConstants.RULE_RESPONSIBILITY_GROUP_ID.equals(getRuleResponsibilityType())) { 123 // setReviewer(getWorkgroupService().getWorkgroup(new 124 // WorkflowGroupId(new 125 // Long(getRuleResponsibilityName()))).getGroupNameId().getNameId()); 126 Group group = KimApiServiceLocator.getGroupService(). 127 getGroup(getRuleResponsibilityName()); 128 setReviewer(group.getName()); 129 setReviewerId(group.getId()); 130 } else if (KewApiConstants.RULE_RESPONSIBILITY_ROLE_ID.equals(getRuleResponsibilityType())) { 131 setRoleReviewer(getRuleResponsibilityName()); 132 setReviewer(getResolvedRoleName()); 133 } 134 } 135 } 136 137 private void injectWebMembers() throws Exception { 138 DelegationRulesProxy delegationRulesProxy = new DelegationRulesProxy(getDelegationRules()); 139 Class delegationRulesClass = getDelegationRules().getClass(); 140 //System.err.println("delegation rules class: "+ delegationRulesClass); 141 Class[] delegationRulesInterfaces = new Class[0]; // = delegationRulesClass.getInterfaces(); 142 List<Class> delegationRulesInterfaceList = (List<Class>) ClassUtils.getAllInterfaces(delegationRulesClass); 143 delegationRulesInterfaces = delegationRulesInterfaceList.toArray(delegationRulesInterfaces); 144 ClassLoader delegationRulesClassLoader = getDelegationRules().getClass().getClassLoader(); 145 Object o = Proxy.newProxyInstance(delegationRulesClassLoader, delegationRulesInterfaces, delegationRulesProxy); 146 //setDelegationRules((List) o); 147 148 if (Integer.parseInt(CoreFrameworkServiceLocator.getParameterService().getParameterValueAsString(KewApiConstants.KEW_NAMESPACE, KRADConstants.DetailTypes.RULE_DETAIL_TYPE, KewApiConstants.RULE_DELEGATE_LIMIT)) > getDelegationRules().size() || showDelegations) { 149 for (Iterator iterator = getDelegationRules().iterator(); iterator.hasNext();) { 150 RuleDelegationBo ruleDelegation = (RuleDelegationBo) iterator.next(); 151 WebRuleBaseValues webRule = new WebRuleBaseValues(); 152 webRule.load(ruleDelegation.getDelegationRule()); 153 webRule.edit(ruleDelegation.getDelegationRule()); 154 ruleDelegation.setDelegationRule(webRule); 155 } 156 } 157 } 158 159 public RuleDelegationBo addNewDelegation() { 160 RuleDelegationBo ruleDelegation = new RuleDelegationBo(); 161 ruleDelegation.setDelegationRule(new WebRuleBaseValues()); 162 ruleDelegation.setDelegationType(DelegationType.PRIMARY); 163 ruleDelegation.getDelegationRule().setDelegateRule(Boolean.TRUE); 164 ruleDelegation.getDelegationRule().setDocTypeName(getRuleBaseValues().getDocTypeName()); 165 getDelegationRules().add(ruleDelegation); 166 showDelegations = true; 167 return ruleDelegation; 168 } 169 170 public String getReviewer() { 171 return reviewer; 172 } 173 174 public void setReviewer(String reviewer) { 175 this.reviewer = reviewer; 176 } 177 178 public void setWorkgroupId(String workgroupId) { 179 Group workgroup = KimApiServiceLocator.getGroupService().getGroup(workgroupId); 180 //Workgroup workgroup = getWorkgroupService().getWorkgroup(new WorkflowGroupId(workgroupId)); 181 if (workgroup != null) { 182 setReviewer(workgroup.getName()); 183 } else { 184 setReviewer(""); 185 } 186 } 187 188 public String getPersonLookupStyle() { 189 return personLookupStyle; 190 } 191 192 public void setPersonLookupStyle(String personLookupStyle) { 193 this.personLookupStyle = personLookupStyle; 194 } 195 196 public String getReviewerStyle() { 197 return reviewerStyle; 198 } 199 200 public void setReviewerStyle(String reviewerStyle) { 201 this.reviewerStyle = reviewerStyle; 202 } 203 204 public String getRoleAreaStyle() { 205 return roleAreaStyle; 206 } 207 208 public void setRoleAreaStyle(String roleAreaLookupStyle) { 209 this.roleAreaStyle = roleAreaLookupStyle; 210 } 211 212 public String getWorkgroupLookupStyle() { 213 return workgroupLookupStyle; 214 } 215 216 public void setWorkgroupLookupStyle(String workgroupLookupStyle) { 217 this.workgroupLookupStyle = workgroupLookupStyle; 218 } 219 220 public RuleDelegationBo getDelegationRule(int index) { 221 while (getDelegationRules().size() <= index) { 222 addNewDelegation(); 223 } 224 return (RuleDelegationBo) getDelegationRules().get(index); 225 } 226 227 public int getNumberOfDelegations() { 228 return numberOfDelegations; 229 } 230 231 public void setNumberOfDelegations(int numberOfDelegations) { 232 this.numberOfDelegations = numberOfDelegations; 233 } 234 235 public boolean isDelegationRulesMaterialized() { 236 return delegationRulesMaterialized; 237 } 238 239 public void setDelegationRulesMaterialized(boolean isDelegationRulesMaterialized) { 240 this.delegationRulesMaterialized = isDelegationRulesMaterialized; 241 } 242 243 public String getRoleReviewer() { 244 return roleReviewer; 245 } 246 247 public void setRoleReviewer(String roleReviewer) { 248 this.roleReviewer = roleReviewer; 249 } 250 251 public int getIndex() { 252 return index; 253 } 254 255 public void setIndex(int index) { 256 this.index = index; 257 } 258 259 public boolean isShowDelegations() { 260 return showDelegations; 261 } 262 263 public void setShowDelegations(boolean showDelegations) { 264 this.showDelegations = showDelegations; 265 } 266 267 public void establishRequiredState() throws Exception { 268 if (KewApiConstants.RULE_RESPONSIBILITY_WORKFLOW_ID.equals(getRuleResponsibilityType())) { 269 reviewerStyle = DISPLAY_INLINE; 270 personLookupStyle = DISPLAY_INLINE; 271 workgroupLookupStyle = DISPLAY_NONE; 272 roleAreaStyle = DISPLAY_NONE; 273 } 274 if (KewApiConstants.RULE_RESPONSIBILITY_GROUP_ID.equals(getRuleResponsibilityType())) { 275 reviewerStyle = DISPLAY_INLINE; 276 personLookupStyle = DISPLAY_NONE; 277 workgroupLookupStyle = DISPLAY_INLINE; 278 roleAreaStyle = DISPLAY_NONE; 279 } 280 if (KewApiConstants.RULE_RESPONSIBILITY_ROLE_ID.equals(getRuleResponsibilityType())) { 281 reviewerStyle = DISPLAY_NONE; 282 personLookupStyle = DISPLAY_NONE; 283 workgroupLookupStyle = DISPLAY_NONE; 284 roleAreaStyle = DISPLAY_INLINE; 285 } 286 loadWebValues(); 287 if (delegationRulesMaterialized) { 288 for (Iterator iterator = getDelegationRules().iterator(); iterator.hasNext();) { 289 RuleDelegationBo delegation = (RuleDelegationBo) iterator.next(); 290 ((WebRuleBaseValues) delegation.getDelegationRule()).establishRequiredState(); 291 } 292 } 293 } 294 295 public void edit(RuleResponsibilityBo ruleResponsibility) throws Exception { 296 load(ruleResponsibility); 297 initialize(); 298 } 299 300 public void load(RuleResponsibilityBo ruleResponsibility) throws Exception { 301 PropertyUtils.copyProperties(this, ruleResponsibility); 302 injectWebMembers(); 303 } 304 305 public void loadDelegations() throws Exception { 306 fetchDelegations(); 307 308 for (Iterator iterator = getDelegationRules().iterator(); iterator.hasNext();) { 309 RuleDelegationBo ruleDelegation = (RuleDelegationBo) iterator.next(); 310 WebRuleBaseValues webRule = new WebRuleBaseValues(); 311 webRule.edit(ruleDelegation.getDelegationRule()); 312 ruleDelegation.setDelegationRule(webRule); 313 } 314 delegationRulesMaterialized = true; 315 populatePreviousRuleIds(); 316 } 317 318 public void populatePreviousRuleIds() { 319 if (delegationRulesMaterialized) { 320 for (Iterator iterator = getDelegationRules().iterator(); iterator.hasNext();) { 321 RuleDelegationBo delegation = (RuleDelegationBo) iterator.next(); 322 ((WebRuleBaseValues) delegation.getDelegationRule()).populatePreviousRuleIds(); 323 } 324 } 325 } 326 327 private void fetchDelegations() { 328 if (getId() != null) { 329 RuleResponsibilityBo responsibility = getRuleService().findByRuleResponsibilityId(getId()); 330 if (responsibility == null) { 331 return; 332 } 333 getDelegationRules().addAll(responsibility.getDelegationRules()); 334 } 335 } 336 337 public void prepareHiddenDelegationsForRoute() { 338 if (showDelegations) { 339 return; 340 } 341 342 fetchDelegations(); 343 344 for (Iterator iter = getDelegationRules().iterator(); iter.hasNext();) { 345 RuleDelegationBo delegation = (RuleDelegationBo) iter.next(); 346 delegation.setDelegateRuleId(null); 347 delegation.setVersionNumber(null); 348 delegation.setRuleDelegationId(null); 349 //delegation.setRuleResponsibility(this); 350 delegation.setResponsibilityId(null); 351 352 RuleBaseValues rule = delegation.getDelegationRule(); 353 rule.setVersionNumber(null); 354 rule.setPreviousRuleId(rule.getId()); 355 rule.setDocumentId(null); 356 rule.setId(null); 357 358 for (Iterator iterator = rule.getRuleResponsibilities().iterator(); iterator.hasNext();) { 359 RuleResponsibilityBo responsibility = (RuleResponsibilityBo) iterator.next(); 360 responsibility.setVersionNumber(null); 361 responsibility.setRuleBaseValuesId(null); 362 responsibility.setRuleBaseValues(rule); 363 responsibility.setId(null); 364 } 365 366 for (Iterator iterator = rule.getRuleExtensions().iterator(); iterator.hasNext();) { 367 RuleExtensionBo extension = (RuleExtensionBo) iterator.next(); 368 extension.setVersionNumber(null); 369 extension.setRuleBaseValues(rule); 370 extension.setRuleBaseValuesId(null); 371 extension.setRuleExtensionId(null); 372 373 for (Iterator iter2 = extension.getExtensionValues().iterator(); iter2.hasNext();) { 374 RuleExtensionValue value = (RuleExtensionValue) iter2.next(); 375 value.setExtension(extension); 376 value.setLockVerNbr(null); 377 value.setRuleExtensionId(null); 378 value.setRuleExtensionValueId(null); 379 } 380 } 381 } 382 } 383 384 public boolean isHasDelegateRuleTemplate() { 385 return hasDelegateRuleTemplate; 386 } 387 388 public void setHasDelegateRuleTemplate(boolean hasDelegateRuleTemplate) { 389 this.hasDelegateRuleTemplate = hasDelegateRuleTemplate; 390 } 391 392 private RuleServiceInternal getRuleService() { 393 return (RuleServiceInternal) KEWServiceLocator.getService(KEWServiceLocator.RULE_SERVICE); 394 } 395 396 /** 397 * Just a little dynamic proxy to keep us from establishing required state 398 * on the delegation rules if they haven't been materialized from the 399 * database yet (they are currenty proxied by OJB) 400 * 401 * @author Kuali Rice Team (rice.collab@kuali.org) 402 */ 403 private class DelegationRulesProxy implements InvocationHandler, java.io.Serializable { 404 405 private static final long serialVersionUID = 7046323200221509473L; 406 407 private List delegationRules; 408 409 public DelegationRulesProxy(List delegationRules) { 410 this.delegationRules = delegationRules; 411 } 412 413 public Object invoke(Object proxy, Method m, Object[] args) throws Throwable { 414 if (!delegationRulesMaterialized && !m.getName().equals("isEmpty") && !m.getName().equals("size")) { 415 for (Iterator iterator = delegationRules.iterator(); iterator.hasNext();) { 416 RuleDelegationBo ruleDelegation = (RuleDelegationBo) iterator.next(); 417 WebRuleBaseValues webRule = new WebRuleBaseValues(); 418 webRule.load(ruleDelegation.getDelegationRule()); 419 webRule.establishRequiredState(); 420 ruleDelegation.setDelegationRule(webRule); 421 } 422 delegationRulesMaterialized = true; 423 424 } 425 return m.invoke(delegationRules, args); 426 } 427 428 } 429 430 }