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.kim.impl.jaxb;
017
018 import java.io.Serializable;
019 import java.util.ArrayList;
020 import java.util.HashSet;
021 import java.util.List;
022 import java.util.Set;
023
024 import javax.xml.bind.Marshaller;
025 import javax.xml.bind.UnmarshalException;
026 import javax.xml.bind.Unmarshaller;
027 import javax.xml.bind.annotation.XmlAccessType;
028 import javax.xml.bind.annotation.XmlAccessorType;
029 import javax.xml.bind.annotation.XmlElement;
030 import javax.xml.bind.annotation.XmlTransient;
031 import javax.xml.bind.annotation.XmlType;
032
033 import org.kuali.rice.core.api.criteria.QueryByCriteria;
034 import org.kuali.rice.core.util.jaxb.RiceXmlExportList;
035 import org.kuali.rice.core.util.jaxb.RiceXmlImportList;
036 import org.kuali.rice.core.util.jaxb.RiceXmlListAdditionListener;
037 import org.kuali.rice.core.util.jaxb.RiceXmlListGetterListener;
038 import org.kuali.rice.kim.api.role.RoleMember;
039 import org.kuali.rice.kim.api.role.RoleMemberContract;
040 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
041
042 import static org.kuali.rice.core.api.criteria.PredicateFactory.equal;
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
051 public 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 }