001    /**
002     * Copyright 2005-2014 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.common.assignee;
017    
018    import org.apache.commons.collections.CollectionUtils;
019    import org.apache.commons.lang.StringUtils;
020    import org.kuali.rice.core.api.CoreConstants;
021    import org.kuali.rice.core.api.mo.AbstractDataTransferObject;
022    import org.kuali.rice.core.api.mo.ModelBuilder;
023    import org.kuali.rice.kim.api.common.delegate.DelegateType;
024    import org.kuali.rice.kim.api.common.delegate.DelegateTypeContract;
025    import org.w3c.dom.Element;
026    
027    import javax.xml.bind.annotation.XmlAccessType;
028    import javax.xml.bind.annotation.XmlAccessorType;
029    import javax.xml.bind.annotation.XmlAnyElement;
030    import javax.xml.bind.annotation.XmlElement;
031    import javax.xml.bind.annotation.XmlElementWrapper;
032    import javax.xml.bind.annotation.XmlRootElement;
033    import javax.xml.bind.annotation.XmlType;
034    import java.io.Serializable;
035    import java.util.ArrayList;
036    import java.util.Collection;
037    import java.util.Collections;
038    import java.util.List;
039    
040    
041    @XmlRootElement(name = Assignee.Constants.ROOT_ELEMENT_NAME)
042    @XmlAccessorType(XmlAccessType.NONE)
043    @XmlType(name = Assignee.Constants.TYPE_NAME, propOrder = {
044            Assignee.Elements.PRINCIPAL_ID,
045            Assignee.Elements.GROUP_ID,
046            Assignee.Elements.DELEGATES,
047            CoreConstants.CommonElements.FUTURE_ELEMENTS
048    })
049    public class Assignee extends AbstractDataTransferObject implements AssigneeContract {
050        @XmlElement(name = Elements.PRINCIPAL_ID, required = false)
051        private final String principalId;
052    
053        @XmlElement(name = Elements.GROUP_ID, required = true)
054        private final String groupId;
055    
056        @XmlElementWrapper(name = Elements.DELEGATES, required = false)
057        @XmlElement(name = Elements.DELEGATE, required = false)
058        private final List<DelegateType> delegates;
059    
060        @SuppressWarnings("unused")
061        @XmlAnyElement
062        private final Collection<Element> _futureElements = null;
063    
064        /**
065             *  A constructor to be used only by JAXB unmarshalling.
066             *  
067             */
068        private Assignee() {
069            this.principalId = null;
070            this.groupId = null;
071            this.delegates = null;
072        }
073     
074        /**
075             * A constructor using the Builder.
076             * 
077             * @param builder
078             */
079        public Assignee(Builder builder) {
080            this.principalId = builder.getPrincipalId();
081            this.groupId = builder.getGroupId();
082            final List<DelegateType> temp = new ArrayList<DelegateType>();
083            if (!CollectionUtils.isEmpty(builder.getDelegates())) {
084                for (DelegateType.Builder delegate: builder.getDelegates()) {
085                    temp.add(delegate.build());
086                }
087            }
088            this.delegates = Collections.unmodifiableList(temp);
089        }
090    
091            /**
092             * @see AssigneeContract#getPrincipalId()
093             */
094            @Override
095            public String getPrincipalId() {
096                    return this.principalId;
097            }
098    
099            /**
100             * @see AssigneeContract#getGroupId()
101             */
102            @Override
103            public String getGroupId() {
104                    return this.groupId;
105            }
106    
107            /**
108             * @see AssigneeContract#getDelegates()
109             */
110            @Override
111            public List<DelegateType> getDelegates() {
112                    return this.delegates;
113            }
114    
115        /**
116         * This builder constructs a PermissionAssignee enforcing the constraints of the {@link AssigneeContract}.
117         */
118        public static final class Builder implements AssigneeContract, ModelBuilder, Serializable {
119            private String principalId;
120            private String groupId;
121            private List<DelegateType.Builder> delegates;
122    
123            private Builder(String principalId, String groupId, List<DelegateType.Builder> delegates) {
124                setPrincipalId(principalId);
125                setGroupId(groupId);
126                setDelegates(delegates);
127            }
128    
129            /**
130             * Creates a KimAttributeData with the required fields.
131             */
132            public static Builder create(String principalId, String groupId, List<DelegateType.Builder> delegates) {
133                return new Builder(principalId, groupId, delegates);
134            }
135    
136            /**
137             * creates a KimAttributeData from an existing {@link org.kuali.rice.kim.api.common.attribute.KimAttributeDataContract}.
138             */
139            public static Builder create(AssigneeContract contract) {
140                final List<DelegateType.Builder> builders = new ArrayList<DelegateType.Builder>();
141                for (DelegateTypeContract d : contract.getDelegates()) {
142                    builders.add(DelegateType.Builder.create(d));
143                }
144    
145                Builder builder = new Builder(contract.getPrincipalId(), contract.getGroupId(), builders);
146                return builder;
147            }
148    
149            @Override
150            public String getPrincipalId() {
151                return principalId;
152            }
153    
154            public void setPrincipalId(final String principalId) {
155                this.principalId = principalId;
156            }
157    
158            @Override
159            public String getGroupId() {
160                return groupId;
161            }
162    
163            public void setGroupId(final String groupId) {
164                    this.groupId = groupId;
165            }
166    
167                    @Override
168                    public List<DelegateType.Builder> getDelegates() {
169                            return delegates;
170                    }
171                    
172            public void setDelegates(final List<DelegateType.Builder> delegates) {
173                    this.delegates = Collections.unmodifiableList(new ArrayList<DelegateType.Builder>(delegates));
174            }               
175                    
176                    @Override
177                    public Assignee build() {
178                        //validate required fields
179                final boolean requiredSet = (groupId != null ^ principalId != null) && delegates != null;
180                if (!requiredSet) {
181                    throw new IllegalStateException("all the required fields are not set");
182                }
183    
184                            return new Assignee(this);
185                    }
186           
187        }
188    
189        /**
190         * Defines some internal constants used on this class.
191         */
192        static class Constants {
193            final static String ROOT_ELEMENT_NAME = "assignee";
194            final static String TYPE_NAME = "assigneeType";
195        }
196    
197        /**
198         * A private class which exposes constants which define the XML element names to use
199         * when this object is marshalled to XML.
200         */
201        static class Elements {
202            final static String PRINCIPAL_ID = "principalId";
203            final static String GROUP_ID = "groupId";
204            final static String DELEGATES = "delegates";
205            final static String DELEGATE = "delegate";
206        }
207    }