View Javadoc
1   /**
2    * Copyright 2005-2015 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package edu.sampleu.travel.workflow;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.kuali.rice.core.api.util.ConcreteKeyValue;
20  import org.kuali.rice.kew.api.WorkflowRuntimeException;
21  import org.kuali.rice.kew.api.identity.Id;
22  import org.kuali.rice.kew.api.identity.PrincipalId;
23  import org.kuali.rice.kew.api.identity.PrincipalName;
24  import org.kuali.rice.kew.api.rule.RoleName;
25  import org.kuali.rice.kew.api.user.UserId;
26  import org.kuali.rice.kew.engine.RouteContext;
27  import org.kuali.rice.kew.exception.WorkflowServiceErrorImpl;
28  import org.kuali.rice.kew.routeheader.DocumentContent;
29  import org.kuali.rice.kew.rule.GenericRoleAttribute;
30  import org.kuali.rice.kew.rule.QualifiedRoleName;
31  import org.kuali.rice.kew.rule.ResolvedQualifiedRole;
32  import org.kuali.rice.kim.api.identity.principal.Principal;
33  import org.kuali.rice.kim.api.services.KimApiServiceLocator;
34  import org.kuali.rice.kns.web.ui.Field;
35  import org.kuali.rice.kns.web.ui.Row;
36  
37  import java.util.ArrayList;
38  import java.util.Collections;
39  import java.util.HashMap;
40  import java.util.List;
41  import java.util.Map;
42  
43  /**
44   * An attribute implementation that can resolve organizational roles
45   */
46  public class EmployeeAttribute extends GenericRoleAttribute {
47      private static final RoleName EMPLOYEE_ROLE = new RoleName(EmployeeAttribute.class.getName(), "employee", "Employee");
48      private static final RoleName SUPERVISOR_ROLE = new RoleName(EmployeeAttribute.class.getName(), "supervisr", "Supervisor");
49      private static final RoleName DIRECTOR_ROLE = new RoleName(EmployeeAttribute.class.getName(), "director", "Dean/Director");
50      private static final List<RoleName> ROLES;
51      static {
52          List<RoleName> tmp = new ArrayList<RoleName>(1);
53          tmp.add(EMPLOYEE_ROLE);
54          tmp.add(SUPERVISOR_ROLE);
55          tmp.add(DIRECTOR_ROLE);
56          ROLES = Collections.unmodifiableList(tmp);
57      }
58  
59  	private static String USERID_FORM_FIELDNAME = "userid";
60  
61      /**
62       * Traveler to be set by client application so that doc content can be generated appropriately
63       */
64  	private String traveler;
65  
66  	//private AttributeParser _attributeParser = new AttributeParser(ATTRIBUTE_TAGNAME);
67  
68  	public EmployeeAttribute() {
69          super("employee");
70  	}
71  
72  	public EmployeeAttribute(String traveler) {
73          super("employee");
74  		this.traveler = traveler;
75  	}
76  
77      /** for edoclite?? */
78      public void setTraveler(String traveler) {
79          this.traveler = traveler;
80      }
81  
82  	/* RoleAttribute methods */
83  	public List<RoleName> getRoleNames() {
84          return ROLES;
85  	}
86  
87      protected boolean isValidRole(String roleName) {
88          for (RoleName role: ROLES) {
89              if (role.getBaseName().equals(roleName)) {
90                  return true;
91              }
92          }
93          return false;
94      }
95  
96  
97  	@Override
98      protected List<String> getRoleNameQualifiers(String roleName, DocumentContent documentContent) {
99          if (!isValidRole(roleName)) {
100             throw new WorkflowRuntimeException("Invalid role: " + roleName);
101         }
102 
103         List<String> qualifiers = new ArrayList<String>();
104         qualifiers.add(roleName);
105         // find all traveller inputs in incoming doc
106 //        List<Map<String, String>> attrs;
107 //        try {
108 //            attrs = content.parseContent(documentContent.getAttributeContent());
109 //        } catch (XPathExpressionException xpee) {
110 //            throw new WorkflowRuntimeException("Error parsing attribute content: " + XmlJotter.jotNode(documentContent.getAttributeContent()));
111 //        }
112 //        for (Map<String, String> props: attrs) {
113 //            String attrTraveler = props.get("traveler");
114 //            if (attrTraveler != null) {
115 //                qualifiers.add(attrTraveler);
116 //            }
117 //        }
118         return qualifiers;
119     }
120 
121 	@Override
122 	protected ResolvedQualifiedRole resolveQualifiedRole(RouteContext routeContext, QualifiedRoleName qualifiedRoleName) {
123         List<Id> recipients = resolveRecipients(routeContext, qualifiedRoleName);
124         ResolvedQualifiedRole rqr = new ResolvedQualifiedRole(getLabelForQualifiedRoleName(qualifiedRoleName),
125                                                               recipients,
126                                                               qualifiedRoleName.getBaseRoleName()); // default to no annotation...
127         return rqr;
128     }
129 	
130 	@Override
131     protected List<Id> resolveRecipients(RouteContext routeContext, QualifiedRoleName qualifiedRoleName) {
132         List<Id> members = new ArrayList<Id>();
133         UserId roleUserId = null;
134         String roleName = qualifiedRoleName.getBaseRoleName();
135         String roleTraveler = qualifiedRoleName.getQualifier();
136 
137         /* EMPLOYEE role routes to traveler */
138         if (StringUtils.equals(EMPLOYEE_ROLE.getBaseName(), roleName)) {
139             roleUserId = new PrincipalId(roleTraveler);
140 
141         /* SUPERVISOR role routes to... supervisor */
142         } else if (StringUtils.equals(SUPERVISOR_ROLE.getBaseName(), roleName)) {
143             // HACK: need to create an organizational-hierarchy service which
144             // has methods like
145             // getSupervisor( user ), getDirector( user ), getSupervised( user
146             // ), etc.
147             // using q.uhuuid() as input
148             roleUserId = new PrincipalName("supervisr");
149 
150         /* SUPERVISOR role routes to... director */
151         } else if (StringUtils.equals(DIRECTOR_ROLE.getBaseName(), roleName)) {
152             // HACK: need to create an organizational-hierarchy service which
153             // has methods like
154             // getSupervisor( user ), getDirector( user ), getSupervised( user
155             // ), etc.
156             // using q.uhuuid() as input
157             roleUserId = new PrincipalName("director");
158         } else {
159             // throw an exception if you get an unrecognized roleName
160             throw new WorkflowRuntimeException("unable to process unknown role '" + roleName + "'");
161         }
162         members.add(roleUserId);
163 
164         return members;
165     }
166 
167     public Map<String, String> getProperties() {
168         Map<String, String> properties = new HashMap<String, String>();
169         properties.put("traveler", traveler);
170         return properties;
171     }
172 
173 	/**
174 	 * Required to support flex routing report
175 	 *
176 	 * @see org.kuali.rice.kew.rule.WorkflowRuleAttribute#getFieldConversions()
177 	 */
178 	public List getFieldConversions() {
179 		List conversionFields = new ArrayList();
180 		conversionFields.add(new ConcreteKeyValue("userid", USERID_FORM_FIELDNAME));
181 		return conversionFields;
182 	}
183 
184 	public List<Row> getRoutingDataRows() {
185 		List<Row> rows = new ArrayList<Row>();
186 
187 		List<Field> fields = new ArrayList<Field>();
188 		fields.add(new Field("Traveler username", "", Field.TEXT, false, USERID_FORM_FIELDNAME, "", false, false, null, null));
189 		rows.add(new Row(fields));
190 
191 		return rows;
192 	}
193 
194 	public List validateRoutingData(Map paramMap) {
195 		List errors = new ArrayList();
196 
197 		String userid = StringUtils.trim((String) paramMap.get(USERID_FORM_FIELDNAME));
198 		if (isRequired() && StringUtils.isBlank(userid)) {
199 			errors.add(new WorkflowServiceErrorImpl("userid is required", "uh.accountattribute.userid.required"));
200 		}
201 
202 		Principal principal = null;
203 		if (!StringUtils.isBlank(userid)) {
204 			principal = KimApiServiceLocator.getIdentityService().getPrincipalByPrincipalName(userid);
205 		}
206 		if (principal == null) {
207 			errors.add(new WorkflowServiceErrorImpl("unable to retrieve user for userid '" + userid + "'", "uh.accountattribute.userid.invalid"));
208 		}
209 	
210 		if (errors.size() == 0) {
211 			traveler = principal.getPrincipalId();
212 		}
213 
214 		return errors;
215 	}
216 }