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.api.role;
017    
018    import org.apache.commons.collections.CollectionUtils;
019    import org.apache.commons.lang.StringUtils;
020    import org.apache.commons.lang.builder.EqualsBuilder;
021    import org.apache.commons.lang.builder.HashCodeBuilder;
022    import org.apache.commons.lang.builder.ToStringBuilder;
023    import org.kuali.rice.core.api.CoreConstants;
024    import org.kuali.rice.core.api.membership.MemberType;
025    import org.kuali.rice.core.api.mo.AbstractDataTransferObject;
026    import org.kuali.rice.core.api.mo.ModelBuilder;
027    import org.kuali.rice.core.api.mo.ModelObjectComplete;
028    import org.kuali.rice.core.api.util.jaxb.MapStringStringAdapter;
029    import org.kuali.rice.kim.api.KimConstants;
030    import org.kuali.rice.kim.api.common.delegate.DelegateType;
031    import org.kuali.rice.kim.api.common.delegate.DelegateTypeContract;
032    import org.w3c.dom.Element;
033    
034    import javax.xml.bind.annotation.XmlAccessType;
035    import javax.xml.bind.annotation.XmlAccessorType;
036    import javax.xml.bind.annotation.XmlAnyElement;
037    import javax.xml.bind.annotation.XmlElement;
038    import javax.xml.bind.annotation.XmlElementWrapper;
039    import javax.xml.bind.annotation.XmlRootElement;
040    import javax.xml.bind.annotation.XmlType;
041    import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
042    import java.util.ArrayList;
043    import java.util.Collection;
044    import java.util.Collections;
045    import java.util.List;
046    import java.util.Map;
047    
048    @XmlRootElement(name = RoleMembership.Constants.ROOT_ELEMENT_NAME)
049    @XmlAccessorType(XmlAccessType.NONE)
050    @XmlType(name = RoleMembership.Constants.TYPE_NAME, propOrder = {
051            RoleMembership.Elements.ROLE_ID,
052            RoleMembership.Elements.ID,
053            RoleMembership.Elements.EMBEDDED_ROLE_ID,
054            RoleMembership.Elements.MEMBER_ID,
055            RoleMembership.Elements.TYPE_CODE,
056            RoleMembership.Elements.ROLE_SORTING_CODE,
057            RoleMembership.Elements.QUALIFIER,
058            RoleMembership.Elements.DELEGATES,
059            CoreConstants.CommonElements.FUTURE_ELEMENTS
060    })
061    public class RoleMembership extends AbstractDataTransferObject implements RoleMembershipContract {
062        private static final long serialVersionUID = 1L;
063    
064        @XmlElement(name=Elements.ROLE_ID, required = true)
065        private final String roleId;
066    
067        @XmlElement(name=Elements.ID, required = false)
068        private final String id;
069    
070        @XmlElement(name=Elements.EMBEDDED_ROLE_ID, required = false)
071        private final String embeddedRoleId;
072    
073        @XmlElement(name=Elements.MEMBER_ID, required = true)
074        private final String memberId;
075    
076        @XmlElement(name=Elements.TYPE_CODE, required = true)
077        private final String typeCode;
078    
079        @XmlElement(name=Elements.ROLE_SORTING_CODE, required = false)
080        private final String roleSortingCode;
081    
082        @XmlElement(name=Elements.QUALIFIER, required = false)
083        @XmlJavaTypeAdapter(value = MapStringStringAdapter.class)
084        private final Map<String, String> qualifier;
085    
086        @XmlElementWrapper(name = Elements.DELEGATES, required = false)
087        @XmlElement(name=Elements.DELEGATE, required = false)
088        private final List<DelegateType> delegates;
089    
090        @SuppressWarnings("unused")
091        @XmlAnyElement
092        private final Collection<Element> _futureElements = null;
093    
094        /**
095         * Private constructor for JAXB only
096         */
097        @SuppressWarnings("unused")
098        private RoleMembership() {
099            roleId = null;
100            id = null;
101            embeddedRoleId = null;
102            memberId = null;
103            typeCode = null;
104            roleSortingCode = null;
105            qualifier = null;
106            delegates = null;
107        }
108    
109        private RoleMembership(Builder b) {
110            roleId = b.getRoleId();
111            id = b.getId();
112            embeddedRoleId = b.getEmbeddedRoleId();
113            memberId = b.getMemberId();
114            typeCode = b.getType().getCode();
115            roleSortingCode = b.getRoleSortingCode();
116            qualifier = b.getQualifier();
117    
118            delegates = new ArrayList<DelegateType>();
119            if (!CollectionUtils.isEmpty(b.getDelegates())) {
120                for (DelegateType.Builder delegateBuilder : b.getDelegates()) {
121                    delegates.add(delegateBuilder.build());
122                }
123            }
124        }
125    
126        @Override
127        public String getRoleId() {
128            return roleId;
129        }
130    
131        @Override
132        public String getId() {
133            return id;
134        }
135    
136        @Override
137        public String getEmbeddedRoleId() {
138            return embeddedRoleId;
139        }
140    
141        @Override
142        public String getMemberId() {
143            return memberId;
144        }
145    
146        @Override
147        public MemberType getType() {
148            return MemberType.fromCode(typeCode);
149        }
150    
151        @Override
152        public String getRoleSortingCode() {
153            return roleSortingCode;
154        }
155    
156        @Override
157        public Map<String, String> getQualifier() {
158            return qualifier;
159        }
160    
161        @Override
162        public List<DelegateType> getDelegates() {
163            return Collections.unmodifiableList(delegates);
164        }
165    
166    
167        public static final class Builder implements ModelBuilder, RoleMembershipContract, ModelObjectComplete {
168            private String roleId;
169            private String id;
170            private String embeddedRoleId;
171            private String memberId;
172            private MemberType type;
173            private String roleSortingCode;
174            private Map<String, String> qualifier;
175            private List<DelegateType.Builder> delegates;
176    
177            private Builder(String roleId, String memberId, MemberType type) {
178                setRoleId(roleId);
179                setMemberId(memberId);
180                setType(type);
181            }
182    
183            public static Builder create(String roleId, String id, String memberId, MemberType memberType,
184                                         Map<String, String> qualifier) {
185    
186                Builder b = new Builder(roleId, memberId, memberType);
187                b.setId(id);
188                b.setQualifier(qualifier);
189                return b;
190            }
191    
192            public static Builder create(RoleMembershipContract contract) {
193                Builder b = new Builder(contract.getRoleId(), contract.getMemberId(), contract.getType());
194                b.setId(contract.getId());
195                b.setEmbeddedRoleId(contract.getEmbeddedRoleId());
196                b.setRoleSortingCode(contract.getRoleSortingCode());
197                b.setQualifier(contract.getQualifier());
198    
199                List<DelegateType.Builder> delegateBuilders = new ArrayList<DelegateType.Builder>();
200                if (!CollectionUtils.isEmpty(contract.getDelegates())) {
201                    for (DelegateTypeContract delegateContract : contract.getDelegates()) {
202                        delegateBuilders.add(DelegateType.Builder.create(delegateContract));
203                    }
204                }
205                b.setDelegates(delegateBuilders);
206    
207                return b;
208            }
209    
210            @Override
211            public RoleMembership build() {
212                return new RoleMembership(this);
213            }
214    
215            @Override
216            public String getRoleId() {
217                return this.roleId;
218            }
219    
220            public void setRoleId(String roleId) {
221                this.roleId = roleId;
222            }
223    
224            @Override
225            public Map<String, String> getQualifier() {
226                return this.qualifier;
227            }
228    
229            public void setQualifier(Map<String, String> qualifier) {
230                this.qualifier = qualifier;
231            }
232    
233            @Override
234            public List<DelegateType.Builder> getDelegates() {
235                return this.delegates;
236            }
237    
238            public void setDelegates(List<DelegateType.Builder> delegates) {
239                this.delegates = delegates;
240            }
241    
242            @Override
243            public String getId() {
244                return this.id;
245            }
246    
247            public void setId(String id) {
248                this.id = id;
249            }
250    
251            @Override
252            public String getMemberId() {
253                return this.memberId;
254            }
255    
256            public void setMemberId(String memberId) {
257                if (StringUtils.isEmpty(memberId)) {
258                    throw new IllegalArgumentException("memberId cannot be empty or null");
259                }
260                this.memberId = memberId;
261            }
262    
263            @Override
264            public MemberType getType() {
265                return this.type;
266            }
267    
268            public void setType(MemberType type) {
269                if (type == null) {
270                    throw new IllegalArgumentException("type cannot be null");
271                }
272                this.type = type;
273            }
274    
275            @Override
276            public String getEmbeddedRoleId() {
277                return this.embeddedRoleId;
278            }
279    
280            public void setEmbeddedRoleId(String embeddedRoleId) {
281                this.embeddedRoleId = embeddedRoleId;
282            }
283    
284            @Override
285            public String getRoleSortingCode() {
286                return this.roleSortingCode;
287            }
288    
289            public void setRoleSortingCode(String roleSortingCode) {
290                this.roleSortingCode = roleSortingCode;
291            }
292    
293            @Override
294            public int hashCode() {
295                return HashCodeBuilder.reflectionHashCode(this);
296            }
297    
298            @Override
299            public boolean equals(Object obj) {
300                return EqualsBuilder.reflectionEquals(obj, this);
301            }
302    
303            @Override
304            public String toString() {
305                return ToStringBuilder.reflectionToString(this);
306            }
307    
308    
309        }
310    
311        /**
312         * A private class which exposes constants which define the XML element names to use
313         * when this object is marshalled to XML.
314         */
315        static class Elements {
316            final static String ROLE_ID = "roleId";
317            final static String ID = "id";
318            final static String EMBEDDED_ROLE_ID = "embeddedRoleId";
319            final static String MEMBER_ID = "memberId";
320            final static String TYPE_CODE = "typeCode";
321            final static String ROLE_SORTING_CODE = "roleSortingCode";
322            final static String QUALIFIER = "qualifier";
323            final static String DELEGATES = "delegates";
324            final static String DELEGATE = "delegate";
325        }
326    
327        /**
328         * Defines some internal constants used on this class.
329         */
330        static class Constants {
331            final static String ROOT_ELEMENT_NAME = "roleMembership";
332            final static String TYPE_NAME = "RoleMembershipType";
333        }
334    
335        public static class Cache {
336            public static final String NAME = KimConstants.Namespaces.KIM_NAMESPACE_2_0 + "/" + RoleMembership.Constants.TYPE_NAME;
337        }
338    }