001/* 002 * Copyright 2011 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/ecl1.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 */ 016package org.kuali.rice.kim.impl.jaxb; 017 018import static org.kuali.rice.core.api.criteria.PredicateFactory.equal; 019 020import java.io.Serializable; 021import java.util.ArrayList; 022import java.util.HashSet; 023import java.util.List; 024import java.util.Set; 025 026import javax.xml.bind.Marshaller; 027import javax.xml.bind.UnmarshalException; 028import javax.xml.bind.Unmarshaller; 029import javax.xml.bind.annotation.XmlAccessType; 030import javax.xml.bind.annotation.XmlAccessorType; 031import javax.xml.bind.annotation.XmlElement; 032import javax.xml.bind.annotation.XmlTransient; 033import javax.xml.bind.annotation.XmlType; 034 035import org.kuali.rice.core.api.criteria.QueryByCriteria; 036import org.kuali.rice.core.util.jaxb.RiceXmlExportList; 037import org.kuali.rice.core.util.jaxb.RiceXmlImportList; 038import org.kuali.rice.core.util.jaxb.RiceXmlListAdditionListener; 039import org.kuali.rice.core.util.jaxb.RiceXmlListGetterListener; 040import org.kuali.rice.kim.api.role.RoleMember; 041import org.kuali.rice.kim.api.role.RoleMemberContract; 042import org.kuali.rice.kim.api.services.KimApiServiceLocator; 043 044/** 045 * Base class representing an unmarshalled <roleMembers> element. 046 * Refer to the static inner classes for more information about the specific contexts. 047 * 048 * @author Kuali Rice Team (rice.collab@kuali.org) 049 */ 050@XmlTransient 051public abstract class RoleMembersXmlDTO<T extends RoleMemberXmlDTO> implements RiceXmlListAdditionListener<T>, Serializable { 052 053 private static final long serialVersionUID = 1L; 054 055 public abstract List<T> getRoleMembers(); 056 057 public abstract void setRoleMembers(List<T> roleMembers); 058 059 void beforeUnmarshal(Unmarshaller unmarshaller, Object parent) throws UnmarshalException { 060 setRoleMembers(new RiceXmlImportList<T>(this)); 061 } 062 063 void afterUnmarshal(Unmarshaller unmarshaller, Object parent) throws UnmarshalException { 064 setRoleMembers(null); 065 } 066 067 // ======================================================================================================= 068 069 /** 070 * This class represents a <roleMembers> element that is not a child of a <role> element. 071 * 072 * @author Kuali Rice Team (rice.collab@kuali.org) 073 */ 074 @XmlAccessorType(XmlAccessType.FIELD) 075 @XmlType(name="StandaloneRoleMembersType", propOrder={"roleMembers"}) 076 public static class OutsideOfRole extends RoleMembersXmlDTO<RoleMemberXmlDTO.OutsideOfRole> { 077 078 private static final long serialVersionUID = 1L; 079 080 @XmlElement(name="roleMember") 081 private List<RoleMemberXmlDTO.OutsideOfRole> roleMembers; 082 083 /** 084 * @see org.kuali.rice.kim.impl.jaxb.RoleMembersXmlDTO#getRoleMembers() 085 */ 086 @Override 087 public List<RoleMemberXmlDTO.OutsideOfRole> getRoleMembers() { 088 return this.roleMembers; 089 } 090 091 /** 092 * @see org.kuali.rice.kim.impl.jaxb.RoleMembersXmlDTO#setRoleMembers(java.util.List) 093 */ 094 @Override 095 public void setRoleMembers(List<RoleMemberXmlDTO.OutsideOfRole> roleMembers) { 096 this.roleMembers = roleMembers; 097 } 098 099 /** 100 * @see org.kuali.rice.core.util.jaxb.RiceXmlListAdditionListener#newItemAdded(java.lang.Object) 101 */ 102 @Override 103 public void newItemAdded(RoleMemberXmlDTO.OutsideOfRole item) { 104 try { 105 RoleXmlUtil.validateAndPersistNewRoleMember(item); 106 } catch (UnmarshalException e) { 107 throw new RuntimeException(e); 108 } 109 } 110 } 111 112 // ======================================================================================================= 113 114 /** 115 * This class represents a <roleMembers> element that is a child of a <role> element. 116 * 117 * @author Kuali Rice Team (rice.collab@kuali.org) 118 */ 119 @XmlAccessorType(XmlAccessType.FIELD) 120 @XmlType(name="RoleMembersType", propOrder={"roleMembers"}) 121 public static class WithinRole extends RoleMembersXmlDTO<RoleMemberXmlDTO.WithinRole> 122 implements RiceXmlListGetterListener<RoleMemberXmlDTO.WithinRole,String> { 123 124 private static final long serialVersionUID = 1L; 125 126 @XmlElement(name="roleMember") 127 private List<RoleMemberXmlDTO.WithinRole> roleMembers; 128 129 @XmlTransient 130 private String roleId; 131 132 @XmlTransient 133 private Set<String> existingRoleMemberIds; 134 135 public WithinRole() {} 136 137 public WithinRole(String roleId) { 138 this.roleId = roleId; 139 } 140 141 /** 142 * @see org.kuali.rice.kim.impl.jaxb.RoleMembersXmlDTO#getRoleMembers() 143 */ 144 @Override 145 public List<org.kuali.rice.kim.impl.jaxb.RoleMemberXmlDTO.WithinRole> getRoleMembers() { 146 return this.roleMembers; 147 } 148 149 /** 150 * @see org.kuali.rice.kim.impl.jaxb.RoleMembersXmlDTO#setRoleMembers(java.util.List) 151 */ 152 @Override 153 public void setRoleMembers(List<org.kuali.rice.kim.impl.jaxb.RoleMemberXmlDTO.WithinRole> roleMembers) { 154 this.roleMembers = roleMembers; 155 } 156 157 /** 158 * @return the roleId 159 */ 160 public String getRoleId() { 161 return this.roleId; 162 } 163 164 /** 165 * @see org.kuali.rice.kim.impl.jaxb.RoleMembersXmlDTO#beforeUnmarshal(javax.xml.bind.Unmarshaller, java.lang.Object) 166 */ 167 @Override 168 void beforeUnmarshal(Unmarshaller unmarshaller, Object parent) throws UnmarshalException { 169 if (parent instanceof RoleXmlDTO) { 170 // Obtain the role ID from the enclosing role, and persist the role if it has not been persisted yet. 171 RoleXmlDTO parentRole = (RoleXmlDTO) parent; 172 if (!parentRole.isAlreadyPersisted()) { 173 RoleXmlUtil.validateAndPersistNewRole(parentRole); 174 } 175 roleId = parentRole.getRoleId(); 176 } 177 existingRoleMemberIds = new HashSet<String>(); 178 super.beforeUnmarshal(unmarshaller, parent); 179 } 180 181 /** 182 * This overridden method ... 183 * 184 * @see org.kuali.rice.kim.impl.jaxb.RoleMembersXmlDTO#afterUnmarshal(javax.xml.bind.Unmarshaller, java.lang.Object) 185 */ 186 @Override 187 void afterUnmarshal(Unmarshaller unmarshaller, Object parent) throws UnmarshalException { 188 super.afterUnmarshal(unmarshaller, parent); 189 if (parent instanceof RoleXmlDTO) { 190 ((RoleXmlDTO)parent).setExistingRoleMemberIds(existingRoleMemberIds); 191 } 192 existingRoleMemberIds = null; 193 } 194 195 /** 196 * @see org.kuali.rice.core.util.jaxb.RiceXmlListAdditionListener#newItemAdded(java.lang.Object) 197 */ 198 @Override 199 public void newItemAdded(org.kuali.rice.kim.impl.jaxb.RoleMemberXmlDTO.WithinRole item) { 200 // Persist the role member and add it to the set of role members that should not be removed from the role. 201 try { 202 existingRoleMemberIds.add(RoleXmlUtil.validateAndPersistNewRoleMember(item)); 203 } catch (UnmarshalException e) { 204 throw new RuntimeException(e); 205 } 206 } 207 208 void beforeMarshal(Marshaller marshaller) { 209 List<RoleMember> tempMembers = KimApiServiceLocator.getRoleService().findRoleMembers( 210 QueryByCriteria.Builder.fromPredicates(equal("roleId", roleId))).getResults(); 211 if (tempMembers != null && !tempMembers.isEmpty()) { 212 List<String> roleMemberIds = new ArrayList<String>(); 213 214 for (RoleMemberContract tempMember : tempMembers) { 215 if (tempMember.isActive(null)) { 216 roleMemberIds.add(tempMember.getId()); 217 } 218 } 219 220 if (!roleMemberIds.isEmpty()) { 221 setRoleMembers(new RiceXmlExportList<RoleMemberXmlDTO.WithinRole,String>(roleMemberIds, this)); 222 } 223 } 224 } 225 226 void afterMarshal(Marshaller marshaller) { 227 setRoleMembers(null); 228 } 229 230 /** 231 * @see org.kuali.rice.core.util.jaxb.RiceXmlListGetterListener#gettingNextItem(java.lang.Object, int) 232 */ 233 @Override 234 public RoleMemberXmlDTO.WithinRole gettingNextItem(String nextItem, int index) { 235 return new RoleMemberXmlDTO.WithinRole(KimApiServiceLocator.getRoleService().findRoleMembers(QueryByCriteria.Builder.fromPredicates(equal("roleMemberId", nextItem))).getResults().get(0), false); 236 } 237 } 238}