001/**
002 * Copyright 2005-2015 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.kew.api.peopleflow;
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.membership.MemberType;
022import org.kuali.rice.core.api.mo.AbstractDataTransferObject;
023import org.kuali.rice.core.api.mo.ModelBuilder;
024import org.kuali.rice.core.api.mo.ModelObjectUtils;
025import org.kuali.rice.kew.api.action.ActionRequestPolicy;
026import org.w3c.dom.Element;
027
028import javax.xml.bind.annotation.XmlAccessType;
029import javax.xml.bind.annotation.XmlAccessorType;
030import javax.xml.bind.annotation.XmlAnyElement;
031import javax.xml.bind.annotation.XmlElement;
032import javax.xml.bind.annotation.XmlElementWrapper;
033import javax.xml.bind.annotation.XmlRootElement;
034import javax.xml.bind.annotation.XmlType;
035import java.io.Serializable;
036import java.util.ArrayList;
037import java.util.Collection;
038import java.util.List;
039
040@XmlRootElement(name = PeopleFlowMember.Constants.ROOT_ELEMENT_NAME)
041@XmlAccessorType(XmlAccessType.NONE)
042@XmlType(name = PeopleFlowMember.Constants.TYPE_NAME, propOrder = {
043        PeopleFlowMember.Elements.MEMBER_ID,
044        PeopleFlowMember.Elements.MEMBER_TYPE,
045        PeopleFlowMember.Elements.ACTION_REQUEST_POLICY,
046        PeopleFlowMember.Elements.RESPONSIBILITY_ID,
047        PeopleFlowMember.Elements.PRIORITY,
048        PeopleFlowMember.Elements.DELEGATES,
049        PeopleFlowMember.Elements.FORCE_ACTION,
050        CoreConstants.CommonElements.FUTURE_ELEMENTS
051})
052public final class PeopleFlowMember extends AbstractDataTransferObject implements PeopleFlowMemberContract {
053
054    private static final int STARTING_PRIORITY = 1;
055
056    @XmlElement(name = Elements.MEMBER_ID, required = true)
057    private final String memberId;
058
059    @XmlElement(name = Elements.MEMBER_TYPE, required = true)
060    private final MemberType memberType;
061
062    @XmlElement(name = Elements.ACTION_REQUEST_POLICY, required = false)
063    private final ActionRequestPolicy actionRequestPolicy;
064
065    @XmlElement(name = Elements.RESPONSIBILITY_ID, required = false)
066    private final String responsibilityId;
067
068    @XmlElement(name = Elements.PRIORITY, required = true)
069    private final int priority;
070
071    @XmlElementWrapper(name = Elements.DELEGATES, required = false)
072    @XmlElement(name = Elements.DELEGATE, required = false)
073    private final List<PeopleFlowDelegate> delegates;
074
075    @XmlElement(name = Elements.FORCE_ACTION, required = false)
076    private Boolean forceAction;
077
078    @SuppressWarnings("unused")
079    @XmlAnyElement
080    private final Collection<Element> _futureElements = null;
081
082    /**
083     * Private constructor used only by JAXB.
084     */
085    private PeopleFlowMember() {
086        this.memberId = null;
087        this.memberType = null;
088        this.actionRequestPolicy = null;
089        this.responsibilityId = null;
090        this.priority = STARTING_PRIORITY;
091        this.delegates = null;
092        this.forceAction = true;
093    }
094
095    private PeopleFlowMember(Builder builder) {
096        this.memberId = builder.getMemberId();
097        this.memberType = builder.getMemberType();
098        this.actionRequestPolicy = builder.getActionRequestPolicy();
099        this.responsibilityId = builder.getResponsibilityId();
100        this.priority = builder.getPriority();
101        this.delegates = ModelObjectUtils.buildImmutableCopy(builder.getDelegates());
102        this.forceAction = builder.getForceAction();
103    }
104
105    @Override
106    public String getMemberId() {
107        return this.memberId;
108    }
109
110    @Override
111    public MemberType getMemberType() {
112        return this.memberType;
113    }
114
115    @Override
116    public ActionRequestPolicy getActionRequestPolicy() {
117        return this.actionRequestPolicy;
118    }
119
120    @Override
121    public String getResponsibilityId() {
122        return this.responsibilityId;
123    }
124
125    @Override
126    public int getPriority() {
127        return this.priority;
128    }
129
130    @Override
131    public List<PeopleFlowDelegate> getDelegates() {
132        return this.delegates;
133    }
134
135    @Override
136    public Boolean getForceAction() {
137        return forceAction;
138    }
139
140    /**
141     * A builder which can be used to construct {@link PeopleFlowMember} instances.  Enforces the constraints of the
142     * {@link PeopleFlowMemberContract}.
143     */
144    public final static class Builder implements Serializable, ModelBuilder, PeopleFlowMemberContract {
145
146        private String memberId;
147        private MemberType memberType;
148        private ActionRequestPolicy actionRequestPolicy;
149        private String responsibilityId;
150        private int priority;
151        private List<PeopleFlowDelegate.Builder> delegates;
152        private Boolean forceAction = true;
153
154        private Builder(String memberId, MemberType memberType) {
155            setMemberId(memberId);
156            setMemberType(memberType);
157            setPriority(STARTING_PRIORITY);
158            setDelegates(new ArrayList<PeopleFlowDelegate.Builder>());
159        }
160
161        public static Builder create(String memberId, MemberType memberType) {
162            return new Builder(memberId, memberType);
163        }
164
165        public static Builder create(PeopleFlowMemberContract contract) {
166            Builder builder = createCopy(contract);
167
168            builder.setResponsibilityId(contract.getResponsibilityId());
169            return builder;
170        }
171
172        public static Builder createCopy(PeopleFlowMemberContract contract) {
173            if (contract == null) {
174                throw new IllegalArgumentException("contract was null");
175            }
176
177            Builder builder = create(contract.getMemberId(), contract.getMemberType());
178            builder.setActionRequestPolicy(contract.getActionRequestPolicy());
179            builder.setPriority(contract.getPriority());
180
181            if (CollectionUtils.isNotEmpty(contract.getDelegates())) {
182                for (PeopleFlowDelegateContract delegate : contract.getDelegates()) {
183                    builder.getDelegates().add(PeopleFlowDelegate.Builder.create(delegate));
184                }
185            }
186
187            builder.setForceAction(contract.getForceAction());
188
189            return builder;
190        }
191
192        public PeopleFlowMember build() {
193            return new PeopleFlowMember(this);
194        }
195
196        @Override
197        public String getMemberId() {
198            return this.memberId;
199        }
200
201        @Override
202        public MemberType getMemberType() {
203            return this.memberType;
204        }
205
206        @Override
207        public ActionRequestPolicy getActionRequestPolicy() {
208            return this.actionRequestPolicy;
209        }
210
211        @Override
212        public String getResponsibilityId() {
213            return this.responsibilityId;
214        }
215
216        @Override
217        public int getPriority() {
218            return this.priority;
219        }
220
221        @Override
222        public List<PeopleFlowDelegate.Builder> getDelegates() {
223            return delegates;
224        }
225
226        @Override
227        public Boolean getForceAction() { return forceAction; }
228
229        public void setMemberId(String memberId) {
230            if (StringUtils.isBlank(memberId)) {
231                throw new IllegalArgumentException("memberId was null or blank");
232            }
233            this.memberId = memberId;
234        }
235
236        public void setMemberType(MemberType memberType) {
237            if (memberType == null) {
238                throw new IllegalArgumentException("memberType was null");
239            }
240            this.memberType = memberType;
241        }
242
243        public void setActionRequestPolicy(ActionRequestPolicy actionRequestPolicy) {
244            if (this.memberType.equals(MemberType.ROLE)) {
245                if (actionRequestPolicy == null) {
246                    throw new IllegalArgumentException("actionRequestPolicy was null");
247                }
248                this.actionRequestPolicy = actionRequestPolicy;
249            }
250        }
251
252        public void setResponsibilityId(String responsibilityId) {
253            this.responsibilityId = responsibilityId;
254        }
255
256        public void setPriority(int priority) {
257            if (priority < STARTING_PRIORITY) {
258                throw new IllegalArgumentException("Given priority was smaller than the minimum prior value of " + STARTING_PRIORITY);
259            }
260            this.priority = priority;
261        }
262
263        public void setDelegates(List<PeopleFlowDelegate.Builder> delegates) {
264            this.delegates = delegates;
265        }
266
267        public void setForceAction(Boolean forceAction) {
268            this.forceAction = forceAction;
269
270            if (forceAction == null) {
271                forceAction = true;
272            }
273        }
274    }
275
276    /**
277     * Defines some internal constants used on this class.
278     */
279    static class Constants {
280        final static String ROOT_ELEMENT_NAME = "peopleFlowMember";
281        final static String TYPE_NAME = "PeopleFlowMemberType";
282    }
283
284    /**
285     * A private class which exposes constants which define the XML element names to use when this object is marshalled to XML.
286     */
287    static class Elements {
288        final static String MEMBER_ID = "memberId";
289        final static String MEMBER_TYPE = "memberType";
290        final static String ACTION_REQUEST_POLICY = "actionRequestPolicy";
291        final static String RESPONSIBILITY_ID = "responsibilityId";
292        final static String PRIORITY = "priority";
293        final static String DELEGATES = "delegates";
294        final static String DELEGATE = "delegate";
295        final static String FORCE_ACTION = "forceAction";
296    }
297
298}