View Javadoc

1   package org.kuali.rice.kim.impl.role;
2   
3   import org.apache.commons.collections.CollectionUtils;
4   import org.apache.commons.lang.StringUtils;
5   import org.apache.log4j.Logger;
6   import org.kuali.rice.core.util.jaxb.MapStringStringAdapter;
7   import org.kuali.rice.core.util.jaxb.SqlDateAdapter;
8   import org.kuali.rice.kim.api.role.Role;
9   import org.kuali.rice.kim.api.role.RoleMember;
10  import org.kuali.rice.kim.api.role.RoleUpdateService;
11  import org.kuali.rice.kim.impl.common.delegate.DelegateBo;
12  import org.kuali.rice.kim.impl.common.delegate.DelegateMemberAttributeDataBo;
13  import org.kuali.rice.kim.impl.common.delegate.DelegateMemberBo;
14  import org.kuali.rice.kim.util.KimConstants;
15  import org.kuali.rice.krad.service.KRADServiceLocator;
16  import org.kuali.rice.krad.service.SequenceAccessorService;
17  
18  import javax.jws.WebParam;
19  import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
20  import java.sql.Date;
21  import java.util.ArrayList;
22  import java.util.HashMap;
23  import java.util.List;
24  import java.util.Map;
25  
26  
27  public class RoleUpdateServiceImpl extends RoleServiceBase implements RoleUpdateService {
28      private static final Logger LOG = Logger.getLogger(RoleUpdateServiceImpl.class);
29  
30      @Override
31      public void assignPrincipalToRole(@WebParam(name = "principalId") String principalId, @WebParam(name = "namespaceCode") String namespaceCode, @WebParam(name = "roleName") String roleName, @WebParam(name = "qualifier") @XmlJavaTypeAdapter(value = MapStringStringAdapter.class) Map<String, String> qualifier) throws UnsupportedOperationException {
32          // look up the role
33          RoleBo role = getRoleBoByName(namespaceCode, roleName);
34          role.refreshReferenceObject("members");
35  
36          // check that identical member does not already exist
37          if (doAnyMemberRecordsMatch(role.getMembers(), principalId, Role.PRINCIPAL_MEMBER_TYPE, qualifier)) {
38              return;
39          }
40          // create the new role member object
41          RoleMemberBo newRoleMember = new RoleMemberBo();
42          // get a new ID from the sequence
43          SequenceAccessorService sas = getSequenceAccessorService();
44          Long nextSeq = sas.getNextAvailableSequenceNumber(
45                  KimConstants.SequenceNames.KRIM_ROLE_MBR_ID_S, RoleMemberBo.class);
46          newRoleMember.setRoleMemberId(nextSeq.toString());
47  
48          newRoleMember.setRoleId(role.getId());
49          newRoleMember.setMemberId(principalId);
50          newRoleMember.setMemberTypeCode(Role.PRINCIPAL_MEMBER_TYPE);
51  
52          // build role member attribute objects from the given Map<String, String>
53          addMemberAttributeData(newRoleMember, qualifier, role.getKimTypeId());
54  
55          // add row to member table
56          // When members are added to roles, clients must be notified.
57          getResponsibilityInternalService().saveRoleMember(newRoleMember);
58          getIdentityManagementNotificationService().roleUpdated();
59      }
60  
61      @Override
62      public void assignGroupToRole(@WebParam(name = "groupId") String groupId, @WebParam(name = "namespaceCode") String namespaceCode, @WebParam(name = "roleName") String roleName, @WebParam(name = "qualifier") @XmlJavaTypeAdapter(value = MapStringStringAdapter.class) Map<String, String> qualifier) throws UnsupportedOperationException {
63          // look up the role
64          RoleBo role = getRoleBoByName(namespaceCode, roleName);
65          // check that identical member does not already exist
66          if (doAnyMemberRecordsMatch(role.getMembers(), groupId, Role.GROUP_MEMBER_TYPE, qualifier)) {
67              return;
68          }
69          // create the new role member object
70          RoleMemberBo newRoleMember = new RoleMemberBo();
71          // get a new ID from the sequence
72          SequenceAccessorService sas = getSequenceAccessorService();
73          Long nextSeq = sas.getNextAvailableSequenceNumber(
74                  KimConstants.SequenceNames.KRIM_ROLE_MBR_ID_S, RoleMemberBo.class);
75          newRoleMember.setRoleMemberId(nextSeq.toString());
76  
77          newRoleMember.setRoleId(role.getId());
78          newRoleMember.setMemberId(groupId);
79          newRoleMember.setMemberTypeCode(Role.GROUP_MEMBER_TYPE);
80  
81          // build role member attribute objects from the given Map<String, String>
82          addMemberAttributeData(newRoleMember, qualifier, role.getKimTypeId());
83  
84          // When members are added to roles, clients must be notified.
85          getResponsibilityInternalService().saveRoleMember(newRoleMember);
86          getIdentityManagementNotificationService().roleUpdated();
87      }
88  
89      @Override
90      public void assignRoleToRole(@WebParam(name = "roleId") String roleId, @WebParam(name = "namespaceCode") String namespaceCode, @WebParam(name = "roleName") String roleName, @WebParam(name = "qualifier") @XmlJavaTypeAdapter(value = MapStringStringAdapter.class) Map<String, String> qualifier) throws UnsupportedOperationException {
91          // look up the roleBo
92          RoleBo roleBo = getRoleBoByName(namespaceCode, roleName);
93          // check that identical member does not already exist
94          if (doAnyMemberRecordsMatch(roleBo.getMembers(), roleId, Role.ROLE_MEMBER_TYPE, qualifier)) {
95              return;
96          }
97          // Check to make sure this doesn't create a circular membership
98          if (!checkForCircularRoleMembership(roleId, roleBo)) {
99              throw new IllegalArgumentException("Circular roleBo reference.");
100         }
101         // create the new roleBo member object
102         RoleMemberBo newRoleMember = new RoleMemberBo();
103         // get a new ID from the sequence
104         SequenceAccessorService sas = getSequenceAccessorService();
105         Long nextSeq = sas.getNextAvailableSequenceNumber(
106                 KimConstants.SequenceNames.KRIM_ROLE_MBR_ID_S, RoleMemberBo.class);
107         newRoleMember.setRoleMemberId(nextSeq.toString());
108 
109         newRoleMember.setRoleId(roleBo.getId());
110         newRoleMember.setMemberId(roleId);
111         newRoleMember.setMemberTypeCode(Role.ROLE_MEMBER_TYPE);
112         // build roleBo member attribute objects from the given Map<String, String>
113         addMemberAttributeData(newRoleMember, qualifier, roleBo.getKimTypeId());
114 
115         // When members are added to roles, clients must be notified.
116         getResponsibilityInternalService().saveRoleMember(newRoleMember);
117         getIdentityManagementNotificationService().roleUpdated();
118     }
119 
120     @Override
121     public RoleMember saveRoleMemberForRole(@WebParam(name = "roleMemberId") String roleMemberId, @WebParam(name = "memberId") String memberId, @WebParam(name = "memberTypeCode") String memberTypeCode, @WebParam(name = "roleId") String roleId, @WebParam(name = "qualifications") @XmlJavaTypeAdapter(value = MapStringStringAdapter.class) Map<String, String> qualifications, @XmlJavaTypeAdapter(value = SqlDateAdapter.class) @WebParam(name = "activeFromDate") Date activeFromDate, @XmlJavaTypeAdapter(value = SqlDateAdapter.class) @WebParam(name = "activeToDate") Date activeToDate) throws UnsupportedOperationException {
122         if(StringUtils.isEmpty(roleMemberId) && StringUtils.isEmpty(memberId) && StringUtils.isEmpty(roleId)){
123     		throw new IllegalArgumentException("Either Role member ID or a combination of member ID and roleBo ID must be passed in.");
124     	}
125     	RoleMemberBo origRoleMemberBo;
126     	RoleBo roleBo;
127     	// create the new roleBo member object
128     	RoleMemberBo newRoleMember = new RoleMemberBo();
129     	if(StringUtils.isEmpty(roleMemberId)){
130 	    	// look up the roleBo
131 	    	roleBo = getRoleBo(roleId);
132 	    	// check that identical member does not already exist
133 	    	origRoleMemberBo = matchingMemberRecord( roleBo.getMembers(), memberId, memberTypeCode, qualifications );
134     	} else{
135     		origRoleMemberBo = getRoleMemberBo(roleMemberId);
136     		roleBo = getRoleBo(origRoleMemberBo.getRoleId());
137     	}
138 
139     	if(origRoleMemberBo !=null){
140     		newRoleMember.setRoleMemberId(origRoleMemberBo.getRoleMemberId());
141     		newRoleMember.setVersionNumber(origRoleMemberBo.getVersionNumber());
142     	} else {
143 	    	// get a new ID from the sequence
144 	    	SequenceAccessorService sas = getSequenceAccessorService();
145 	    	Long nextSeq = sas.getNextAvailableSequenceNumber(
146 	    			KimConstants.SequenceNames.KRIM_ROLE_MBR_ID_S, RoleMemberBo.class);
147 	    	newRoleMember.setRoleMemberId( nextSeq.toString() );
148     	}
149     	newRoleMember.setRoleId(roleBo.getId());
150     	newRoleMember.setMemberId( memberId );
151     	newRoleMember.setMemberTypeCode( memberTypeCode );
152 		if (activeFromDate != null) {
153 			newRoleMember.setActiveFromDate(new java.sql.Timestamp(activeFromDate.getTime()));
154 		}
155 		if (activeToDate != null) {
156 			newRoleMember.setActiveToDate(new java.sql.Timestamp(activeToDate.getTime()));
157 		}
158     	// build roleBo member attribute objects from the given Map<String, String>
159     	addMemberAttributeData( newRoleMember, qualifications, roleBo.getKimTypeId() );
160 
161     	// When members are added to roles, clients must be notified.
162     	getResponsibilityInternalService().saveRoleMember(newRoleMember);
163     	deleteNullMemberAttributeData(newRoleMember.getAttributeDetails());
164     	getIdentityManagementNotificationService().roleUpdated();
165 
166     	return findRoleMember(newRoleMember.getRoleMemberId());
167     }
168 
169     @Override
170     public void saveRoleRspActions(@WebParam(name = "roleResponsibilityActionId") String roleResponsibilityActionId, @WebParam(name = "roleId") String roleId, @WebParam(name = "roleResponsibilityId") String roleResponsibilityId, @WebParam(name = "roleMemberId") String roleMemberId, @WebParam(name = "actionTypeCode") String actionTypeCode, @WebParam(name = "actionPolicyCode") String actionPolicyCode, @WebParam(name = "priorityNumber") Integer priorityNumber, @WebParam(name = "forceAction") Boolean forceAction) {
171         RoleResponsibilityActionBo newRoleRspAction = new RoleResponsibilityActionBo();
172 		newRoleRspAction.setActionPolicyCode(actionPolicyCode);
173 		newRoleRspAction.setActionTypeCode(actionTypeCode);
174 		newRoleRspAction.setPriorityNumber(priorityNumber);
175 		newRoleRspAction.setForceAction(forceAction);
176 		newRoleRspAction.setRoleMemberId(roleMemberId);
177 		newRoleRspAction.setRoleResponsibilityId(roleResponsibilityId);
178 		if(StringUtils.isEmpty(roleResponsibilityActionId)){
179 			//If there is an existing one
180 			Map<String, String> criteria = new HashMap<String, String>(1);
181 			criteria.put(KimConstants.PrimaryKeyConstants.ROLE_RESPONSIBILITY_ID, roleResponsibilityId);
182 			criteria.put(KimConstants.PrimaryKeyConstants.ROLE_MEMBER_ID, roleMemberId);
183 			List<RoleResponsibilityActionBo> roleResponsibilityActionImpls = (List<RoleResponsibilityActionBo>)
184 				getBusinessObjectService().findMatching(RoleResponsibilityActionBo.class, criteria);
185 			if(roleResponsibilityActionImpls!=null && roleResponsibilityActionImpls.size()>0){
186 				newRoleRspAction.setId(roleResponsibilityActionImpls.get(0).getId());
187 				newRoleRspAction.setVersionNumber(roleResponsibilityActionImpls.get(0).getVersionNumber());
188 			} else{
189 	//			 get a new ID from the sequence
190 		    	SequenceAccessorService sas = getSequenceAccessorService();
191 		    	Long nextSeq = sas.getNextAvailableSequenceNumber(
192 		    			KimConstants.SequenceNames.KRIM_ROLE_RSP_ACTN_ID_S, RoleResponsibilityActionBo.class);
193 		    	newRoleRspAction.setId(nextSeq.toString());
194 			}
195 		} else{
196 			Map<String, String> criteria = new HashMap<String, String>(1);
197 			criteria.put(KimConstants.PrimaryKeyConstants.ROLE_RESPONSIBILITY_ACTION_ID, roleResponsibilityActionId);
198 			List<RoleResponsibilityActionBo> roleResponsibilityActionImpls = (List<RoleResponsibilityActionBo>)
199 				getBusinessObjectService().findMatching(RoleResponsibilityActionBo.class, criteria);
200 			if(CollectionUtils.isNotEmpty(roleResponsibilityActionImpls) && roleResponsibilityActionImpls.size()>0){
201 				newRoleRspAction.setId(roleResponsibilityActionImpls.get(0).getId());
202 				newRoleRspAction.setVersionNumber(roleResponsibilityActionImpls.get(0).getVersionNumber());
203 			}
204 		}
205 		getBusinessObjectService().save(newRoleRspAction);
206 		getIdentityManagementNotificationService().roleUpdated();
207     }
208 
209     @Override
210     public void saveDelegationMemberForRole(@WebParam(name = "assignedToId") String delegationMemberId, @WebParam(name = "roleMemberId") String roleMemberId, @WebParam(name = "memberId") String memberId, @WebParam(name = "memberTypeCode") String memberTypeCode, @WebParam(name = "delegationTypeCode") String delegationTypeCode, @WebParam(name = "roleId") String roleId, @WebParam(name = "qualifications") @XmlJavaTypeAdapter(value = MapStringStringAdapter.class) Map<String, String> qualifications, @XmlJavaTypeAdapter(value = SqlDateAdapter.class) @WebParam(name = "activeFromDate") Date activeFromDate, @XmlJavaTypeAdapter(value = SqlDateAdapter.class) @WebParam(name = "activeToDate") Date activeToDate) throws UnsupportedOperationException {
211         if(StringUtils.isEmpty(delegationMemberId) && StringUtils.isEmpty(memberId) && StringUtils.isEmpty(roleId)){
212     		throw new IllegalArgumentException("Either Delegation member ID or a combination of member ID and role ID must be passed in.");
213     	}
214     	// look up the role
215     	RoleBo role = getRoleBo(roleId);
216     	DelegateBo delegation = getDelegationOfType(role.getId(), delegationTypeCode);
217     	// create the new role member object
218     	DelegateMemberBo newDelegationMember = new DelegateMemberBo();
219 
220     	DelegateMemberBo origDelegationMember;
221     	if(StringUtils.isNotEmpty(delegationMemberId)){
222     		origDelegationMember = getDelegateMemberBo(delegationMemberId);
223     	} else{
224     		List<DelegateMemberBo> origDelegationMembers =
225                     this.getDelegationMemberBoListByMemberAndDelegationId(memberId, delegation.getDelegationId());
226 	    	origDelegationMember =
227 	    		(origDelegationMembers!=null && origDelegationMembers.size()>0) ? origDelegationMembers.get(0) : null;
228     	}
229     	if(origDelegationMember!=null){
230     		newDelegationMember.setDelegationMemberId(origDelegationMember.getDelegationMemberId());
231     		newDelegationMember.setVersionNumber(origDelegationMember.getVersionNumber());
232     	} else{
233     		newDelegationMember.setDelegationMemberId(getNewDelegationMemberId());
234     	}
235     	newDelegationMember.setMemberId(memberId);
236     	newDelegationMember.setDelegationId(delegation.getDelegationId());
237     	newDelegationMember.setRoleMemberId(roleMemberId);
238     	newDelegationMember.setTypeCode(memberTypeCode);
239 		if (activeFromDate != null) {
240 			newDelegationMember.setActiveFromDate(new java.sql.Timestamp(activeFromDate.getTime()));
241 		}
242 		if (activeToDate != null) {
243 			newDelegationMember.setActiveToDate(new java.sql.Timestamp(activeToDate.getTime()));
244 		}
245 
246     	// build role member attribute objects from the given Map<String, String>
247     	addDelegationMemberAttributeData( newDelegationMember, qualifications, role.getKimTypeId() );
248 
249     	List<DelegateMemberBo> delegationMembers = new ArrayList<DelegateMemberBo>();
250     	delegationMembers.add(newDelegationMember);
251     	delegation.setMembers(delegationMembers);
252 
253     	getBusinessObjectService().save(delegation);
254     	for(DelegateMemberBo delegationMember: delegation.getMembers()){
255     		deleteNullDelegationMemberAttributeData(delegationMember.getAttributes());
256     	}
257     	getIdentityManagementNotificationService().roleUpdated();
258     }
259 
260     @Override
261     public void removePrincipalFromRole(@WebParam(name = "principalId") String principalId, @WebParam(name = "namespaceCode") String namespaceCode, @WebParam(name = "roleName") String roleName, @WebParam(name = "qualifier") @XmlJavaTypeAdapter(value = MapStringStringAdapter.class) Map<String, String> qualifier) throws UnsupportedOperationException {
262         // look up the role
263     	RoleBo role = getRoleBoByName(namespaceCode, roleName);
264     	// pull all the principal members
265     	role.refreshReferenceObject("members");
266     	// look for an exact qualifier match
267 		for ( RoleMemberBo rm : role.getMembers() ) {
268 			if ( doesMemberMatch( rm, principalId, Role.PRINCIPAL_MEMBER_TYPE, qualifier ) ) {
269 		    	// if found, remove
270 				// When members are removed from roles, clients must be notified.
271 		    	getResponsibilityInternalService().removeRoleMember(rm);
272 			}
273 		}
274 		getIdentityManagementNotificationService().roleUpdated();
275     }
276 
277     @Override
278     public void removeGroupFromRole(@WebParam(name = "groupId") String groupId, @WebParam(name = "namespaceCode") String namespaceCode, @WebParam(name = "roleName") String roleName, @WebParam(name = "qualifier") @XmlJavaTypeAdapter(value = MapStringStringAdapter.class) Map<String, String> qualifier) throws UnsupportedOperationException {
279         // look up the roleBo
280     	RoleBo roleBo = getRoleBoByName(namespaceCode, roleName);
281     	// pull all the group roleBo members
282     	// look for an exact qualifier match
283 		for ( RoleMemberBo rm : roleBo.getMembers() ) {
284 			if ( doesMemberMatch( rm, groupId, Role.GROUP_MEMBER_TYPE, qualifier ) ) {
285 		    	// if found, remove
286 				// When members are removed from roles, clients must be notified.
287 		    	getResponsibilityInternalService().removeRoleMember(rm);
288 			}
289 		}
290 		getIdentityManagementNotificationService().roleUpdated();
291     }
292 
293     @Override
294     public void removeRoleFromRole(@WebParam(name = "roleId") String roleId, @WebParam(name = "namespaceCode") String namespaceCode, @WebParam(name = "roleName") String roleName, @WebParam(name = "qualifier") @XmlJavaTypeAdapter(value = MapStringStringAdapter.class) Map<String, String> qualifier) throws UnsupportedOperationException {
295         // look up the role
296     	RoleBo role = getRoleBoByName(namespaceCode, roleName);
297     	// pull all the group role members
298     	// look for an exact qualifier match
299 		for ( RoleMemberBo rm : role.getMembers() ) {
300 			if ( doesMemberMatch( rm, roleId, Role.ROLE_MEMBER_TYPE, qualifier ) ) {
301 		    	// if found, remove
302 				// When members are removed from roles, clients must be notified.
303 		    	getResponsibilityInternalService().removeRoleMember(rm);
304 			}
305 		}
306 		getIdentityManagementNotificationService().roleUpdated();
307     }
308 
309     @Override
310     public void saveRole(@WebParam(name = "roleId") String roleId, @WebParam(name = "roleName") String roleName, @WebParam(name = "roleDescription") String roleDescription, @WebParam(name = "active") boolean active, @WebParam(name = "kimTypeId") String kimTypeId, @WebParam(name = "namespaceCode") String namespaceCode) throws UnsupportedOperationException {
311         // look for existing role
312         RoleBo role = getBusinessObjectService().findBySinglePrimaryKey(RoleBo.class, roleId);
313         if (role == null) {
314             role = new RoleBo();
315             role.setId(roleId);
316         }
317 
318         role.setName(roleName);
319         role.setDescription(roleDescription);
320         role.setActive(active);
321         role.setKimTypeId(kimTypeId);
322         role.setNamespaceCode(namespaceCode);
323 
324         getBusinessObjectService().save(role);
325     }
326 
327     @Override
328     public String getNextAvailableRoleId() throws UnsupportedOperationException {
329         Long nextSeq = KRADServiceLocator.getSequenceAccessorService().getNextAvailableSequenceNumber(KimConstants.SequenceNames.KRIM_ROLE_MBR_ID_S, RoleBo.class);
330 
331         if (nextSeq == null) {
332             LOG.error("Unable to get new role id from sequence " + KimConstants.SequenceNames.KRIM_ROLE_MBR_ID_S);
333             throw new RuntimeException("Unable to get new role id from sequence " + KimConstants.SequenceNames.KRIM_ROLE_MBR_ID_S);
334         }
335 
336         return nextSeq.toString();
337     }
338 
339     @Override
340     public void assignPermissionToRole(String permissionId, String roleId) throws UnsupportedOperationException {
341         RolePermissionBo newRolePermission = new RolePermissionBo();
342 
343         Long nextSeq = KRADServiceLocator.getSequenceAccessorService().getNextAvailableSequenceNumber(KimConstants.SequenceNames.KRIM_ROLE_PERM_ID_S, RolePermissionBo.class);
344 
345         if (nextSeq == null) {
346             LOG.error("Unable to get new role permission id from sequence " + KimConstants.SequenceNames.KRIM_ROLE_PERM_ID_S);
347             throw new RuntimeException("Unable to get new role permission id from sequence " + KimConstants.SequenceNames.KRIM_ROLE_PERM_ID_S);
348         }
349 
350         newRolePermission.setId(nextSeq.toString());
351         newRolePermission.setRoleId(roleId);
352         newRolePermission.setPermissionId(permissionId);
353         newRolePermission.setActive(true);
354 
355         getBusinessObjectService().save(newRolePermission);
356         getIdentityManagementNotificationService().roleUpdated();
357     }
358 
359     protected void addMemberAttributeData(RoleMemberBo roleMember, Map<String, String> qualifier, String kimTypeId) {
360         List<RoleMemberAttributeDataBo> attributes = new ArrayList<RoleMemberAttributeDataBo>();
361         for (String attributeName : qualifier.keySet()) {
362             RoleMemberAttributeDataBo roleMemberAttrBo = new RoleMemberAttributeDataBo();
363             roleMemberAttrBo.setAttributeValue(qualifier.get(attributeName));
364             roleMemberAttrBo.setKimTypeId(kimTypeId);
365             roleMemberAttrBo.setAssignedToId(roleMember.getRoleMemberId());
366             // look up the attribute ID
367             roleMemberAttrBo.setKimAttributeId(getKimAttributeId(attributeName));
368 
369             Map<String, String> criteria = new HashMap<String, String>();
370             criteria.put(KimConstants.PrimaryKeyConstants.KIM_ATTRIBUTE_ID, roleMemberAttrBo.getKimAttributeId());
371             criteria.put(KimConstants.PrimaryKeyConstants.ROLE_MEMBER_ID, roleMember.getRoleMemberId());
372             List<RoleMemberAttributeDataBo> origRoleMemberAttributes =
373                     (List<RoleMemberAttributeDataBo>) getBusinessObjectService().findMatching(RoleMemberAttributeDataBo.class, criteria);
374             RoleMemberAttributeDataBo origRoleMemberAttribute =
375                     (origRoleMemberAttributes != null && origRoleMemberAttributes.size() > 0) ? origRoleMemberAttributes.get(0) : null;
376             if (origRoleMemberAttribute != null) {
377                 roleMemberAttrBo.setId(origRoleMemberAttribute.getId());
378                 roleMemberAttrBo.setVersionNumber(origRoleMemberAttribute.getVersionNumber());
379             } else {
380                 // pull the next sequence number for the data ID
381                 roleMemberAttrBo.setId(getNewAttributeDataId());
382             }
383             attributes.add(roleMemberAttrBo);
384         }
385         roleMember.setAttributeDetails(attributes);
386     }
387 
388     protected void addDelegationMemberAttributeData( DelegateMemberBo delegationMember, Map<String, String> qualifier, String kimTypeId ) {
389 		List<DelegateMemberAttributeDataBo> attributes = new ArrayList<DelegateMemberAttributeDataBo>();
390 		for ( String attributeName : qualifier.keySet() ) {
391 			DelegateMemberAttributeDataBo delegateMemberAttrBo = new DelegateMemberAttributeDataBo();
392 			delegateMemberAttrBo.setAttributeValue(qualifier.get(attributeName));
393 			delegateMemberAttrBo.setKimTypeId(kimTypeId);
394 			delegateMemberAttrBo.setAssignedToId(delegationMember.getDelegationMemberId());
395 			// look up the attribute ID
396 			delegateMemberAttrBo.setKimAttributeId(getKimAttributeId(attributeName));
397 	    	Map<String, String> criteria = new HashMap<String, String>();
398 	    	criteria.put(KimConstants.PrimaryKeyConstants.KIM_ATTRIBUTE_ID, delegateMemberAttrBo.getKimAttributeId());
399 	    	criteria.put(KimConstants.PrimaryKeyConstants.DELEGATION_MEMBER_ID, delegationMember.getDelegationMemberId());
400 			List<DelegateMemberAttributeDataBo> origDelegationMemberAttributes =
401 	    		(List<DelegateMemberAttributeDataBo>)getBusinessObjectService().findMatching(DelegateMemberAttributeDataBo.class, criteria);
402 			DelegateMemberAttributeDataBo origDelegationMemberAttribute =
403 	    		(origDelegationMemberAttributes!=null && origDelegationMemberAttributes.size()>0) ? origDelegationMemberAttributes.get(0) : null;
404 	    	if(origDelegationMemberAttribute!=null){
405 	    		delegateMemberAttrBo.setId(origDelegationMemberAttribute.getId());
406 	    		delegateMemberAttrBo.setVersionNumber(origDelegationMemberAttribute.getVersionNumber());
407 	    	} else{
408 				// pull the next sequence number for the data ID
409 				delegateMemberAttrBo.setId(getNewAttributeDataId());
410 	    	}
411 			attributes.add( delegateMemberAttrBo );
412 		}
413 		delegationMember.setAttributes( attributes );
414 	}
415 
416 
417 
418      // --------------------
419     // Persistence Methods
420     // --------------------
421 
422 	private void deleteNullMemberAttributeData(List<RoleMemberAttributeDataBo> attributes) {
423 		List<RoleMemberAttributeDataBo> attributesToDelete = new ArrayList<RoleMemberAttributeDataBo>();
424 		for(RoleMemberAttributeDataBo attribute: attributes){
425 			if(attribute.getAttributeValue()==null){
426 				attributesToDelete.add(attribute);
427 			}
428 		}
429 		getBusinessObjectService().delete(attributesToDelete);
430 	}
431 
432     private void deleteNullDelegationMemberAttributeData(List<DelegateMemberAttributeDataBo> attributes) {
433         List<DelegateMemberAttributeDataBo> attributesToDelete = new ArrayList<DelegateMemberAttributeDataBo>();
434 
435 		for(DelegateMemberAttributeDataBo attribute: attributes){
436 			if(attribute.getAttributeValue()==null){
437 				attributesToDelete.add(attribute);
438 			}
439 		}
440 		getBusinessObjectService().delete(attributesToDelete);
441 	}
442 }