001/**
002 * Copyright 2005-2016 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 */
016package org.kuali.rice.kim.api.common.assignee;
017
018import org.apache.commons.collections.CollectionUtils;
019import org.apache.commons.lang.StringUtils;
020import org.kuali.rice.core.api.CoreConstants;
021import org.kuali.rice.core.api.mo.AbstractDataTransferObject;
022import org.kuali.rice.core.api.mo.ModelBuilder;
023import org.kuali.rice.kim.api.common.delegate.DelegateType;
024import org.kuali.rice.kim.api.common.delegate.DelegateTypeContract;
025import org.w3c.dom.Element;
026
027import javax.xml.bind.annotation.XmlAccessType;
028import javax.xml.bind.annotation.XmlAccessorType;
029import javax.xml.bind.annotation.XmlAnyElement;
030import javax.xml.bind.annotation.XmlElement;
031import javax.xml.bind.annotation.XmlElementWrapper;
032import javax.xml.bind.annotation.XmlRootElement;
033import javax.xml.bind.annotation.XmlType;
034import java.io.Serializable;
035import java.util.ArrayList;
036import java.util.Collection;
037import java.util.Collections;
038import 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})
049public 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}