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.kim.api.responsibility;
017
018import com.google.common.collect.Maps;
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.core.api.util.jaxb.MapStringStringAdapter;
024import org.kuali.rice.kim.api.common.delegate.DelegateType;
025import org.kuali.rice.kim.api.common.delegate.DelegateTypeContract;
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 javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
036import java.io.Serializable;
037import java.util.ArrayList;
038import java.util.Collection;
039import java.util.Collections;
040import java.util.List;
041import java.util.Map;
042
043@XmlRootElement(name = ResponsibilityAction.Constants.ROOT_ELEMENT_NAME)
044@XmlAccessorType(XmlAccessType.NONE)
045@XmlType(name = ResponsibilityAction.Constants.TYPE_NAME, propOrder = {
046        ResponsibilityAction.Elements.PRINCIPAL_ID,
047        ResponsibilityAction.Elements.ROLE_RESPONSIBILITY_ACTION_ID,
048        ResponsibilityAction.Elements.PARALLEL_ROUTING_GROUPING_CODE,
049        ResponsibilityAction.Elements.ACTION_TYPE_CODE,
050        ResponsibilityAction.Elements.ACTION_POLICY_CODE,
051        ResponsibilityAction.Elements.PRIORITY_NUMBER,
052        ResponsibilityAction.Elements.GROUP_ID,
053        ResponsibilityAction.Elements.MEMBER_ROLE_ID,
054        ResponsibilityAction.Elements.RESPONSIBILITY_NAME,
055        ResponsibilityAction.Elements.RESPONSIBILITY_ID,
056        ResponsibilityAction.Elements.RESPONSIBILITY_NAMESPACE_CODE,
057        ResponsibilityAction.Elements.FORCE_ACTION,
058        ResponsibilityAction.Elements.QUALIFIER,
059        ResponsibilityAction.Elements.DELEGATES,
060        ResponsibilityAction.Elements.ROLE_ID,
061        CoreConstants.CommonElements.FUTURE_ELEMENTS
062})
063public final class ResponsibilityAction extends AbstractDataTransferObject
064        implements ResponsibilityActionContract {
065
066    @XmlElement(name = Elements.PRINCIPAL_ID, required = false)
067    private final String principalId;
068
069    @XmlElement(name = Elements.ROLE_RESPONSIBILITY_ACTION_ID, required = false)
070    private final String roleResponsibilityActionId;
071
072    @XmlElement(name = Elements.PARALLEL_ROUTING_GROUPING_CODE, required = false)
073    private final String parallelRoutingGroupingCode;
074
075    @XmlElement(name = Elements.ACTION_TYPE_CODE, required = false)
076    private final String actionTypeCode;
077
078    @XmlElement(name = Elements.ACTION_POLICY_CODE, required = false)
079    private final String actionPolicyCode;
080
081    @XmlElement(name = Elements.PRIORITY_NUMBER, required = false)
082    private final Integer priorityNumber;
083
084    @XmlElement(name = Elements.GROUP_ID, required = true)
085    private final String groupId;
086
087    @XmlElement(name = Elements.MEMBER_ROLE_ID, required = true)
088    private final String memberRoleId;
089
090    @XmlElement(name = Elements.RESPONSIBILITY_NAME, required = true)
091    private final String responsibilityName;
092
093    @XmlElement(name = Elements.RESPONSIBILITY_ID, required = true)
094    private final String responsibilityId;
095
096    @XmlElement(name = Elements.RESPONSIBILITY_NAMESPACE_CODE, required = true)
097    private final String responsibilityNamespaceCode;
098
099    @XmlElement(name = Elements.FORCE_ACTION, required = true)
100    private final boolean forceAction;
101
102    @XmlElement(name = Elements.QUALIFIER, required = true)
103    @XmlJavaTypeAdapter(value = MapStringStringAdapter.class)
104    private final Map<String, String> qualifier;
105
106    @XmlElementWrapper(name = Elements.DELEGATES, required = false)
107    @XmlElement(name = Elements.DELEGATE, required = true)
108    private final List<DelegateType> delegates;
109
110    @XmlElement(name = Elements.ROLE_ID, required = true)
111    private final String roleId;
112
113    @SuppressWarnings("unused")
114    @XmlAnyElement
115    private final Collection<Element> _futureElements = null;
116
117    /**
118     * Private constructor used only by JAXB.
119     */
120    private ResponsibilityAction() {
121        this.principalId = null;
122        this.roleResponsibilityActionId = null;
123        this.parallelRoutingGroupingCode = null;
124        this.actionTypeCode = null;
125        this.actionPolicyCode = null;
126        this.priorityNumber = null;
127        this.groupId = null;
128        this.memberRoleId = null;
129        this.responsibilityName = null;
130        this.responsibilityId = null;
131        this.responsibilityNamespaceCode = null;
132        this.forceAction = false;
133        this.qualifier = null;
134        this.delegates = null;
135        this.roleId = null;
136    }
137
138    private ResponsibilityAction(Builder builder) {
139        this.principalId = builder.getPrincipalId();
140        this.roleResponsibilityActionId = builder.getRoleResponsibilityActionId();
141        this.parallelRoutingGroupingCode = builder.getParallelRoutingGroupingCode();
142        this.actionTypeCode = builder.getActionTypeCode();
143        this.actionPolicyCode = builder.getActionPolicyCode();
144        this.priorityNumber = builder.getPriorityNumber();
145        this.groupId = builder.getGroupId();
146        this.memberRoleId = builder.getMemberRoleId();
147        this.responsibilityName = builder.getResponsibilityName();
148        this.responsibilityId = builder.getResponsibilityId();
149        this.responsibilityNamespaceCode = builder.getResponsibilityNamespaceCode();
150        this.forceAction = builder.isForceAction();
151        this.qualifier = builder.getQualifier();
152        final List<DelegateType> ds = new ArrayList<DelegateType>();
153        for (DelegateType.Builder d : builder.getDelegates()) {
154            if (d != null) {
155                ds.add(d.build());
156            }
157        }
158        this.delegates = ds;
159        this.roleId = builder.getRoleId();
160    }
161
162    @Override
163    public String getPrincipalId() {
164        return this.principalId;
165    }
166
167    @Override
168    public String getRoleResponsibilityActionId() {
169        return this.roleResponsibilityActionId;
170    }
171
172    @Override
173    public String getParallelRoutingGroupingCode() {
174        return this.parallelRoutingGroupingCode;
175    }
176
177    @Override
178    public String getActionTypeCode() {
179        return this.actionTypeCode;
180    }
181
182    @Override
183    public String getActionPolicyCode() {
184        return this.actionPolicyCode;
185    }
186
187    @Override
188    public Integer getPriorityNumber() {
189        return this.priorityNumber;
190    }
191
192    @Override
193    public String getGroupId() {
194        return this.groupId;
195    }
196
197    @Override
198    public String getMemberRoleId() {
199        return this.memberRoleId;
200    }
201
202    @Override
203    public String getResponsibilityName() {
204        return this.responsibilityName;
205    }
206
207    @Override
208    public String getResponsibilityId() {
209        return this.responsibilityId;
210    }
211
212    @Override
213    public String getResponsibilityNamespaceCode() {
214        return this.responsibilityNamespaceCode;
215    }
216
217    @Override
218    public boolean isForceAction() {
219        return this.forceAction;
220    }
221
222    @Override
223    public Map<String, String> getQualifier() {
224        return this.qualifier;
225    }
226
227    @Override
228    public List<DelegateType> getDelegates() {
229        return Collections.unmodifiableList(this.delegates);
230    }
231
232    @Override
233    public String getRoleId() {
234        return this.roleId;
235    }
236
237
238    /**
239     * A builder which can be used to construct {@link ResponsibilityAction} instances.  Enforces the constraints of the {@link ResponsibilityActionContract}.
240     */
241    public final static class Builder
242            implements Serializable, ModelBuilder, ResponsibilityActionContract {
243
244        private String principalId;
245        private String roleResponsibilityActionId;
246        private String parallelRoutingGroupingCode;
247        private String actionTypeCode;
248        private String actionPolicyCode;
249        private Integer priorityNumber;
250        private String groupId;
251        private String memberRoleId;
252        private String responsibilityName;
253        private String responsibilityId;
254        private String responsibilityNamespaceCode;
255        private boolean forceAction;
256        private Map<String, String> qualifier;
257        private List<DelegateType.Builder> delegates;
258        private String roleId;
259
260        private Builder() {
261        }
262
263        /**
264         * All required fields are enforced in the {@link org.kuali.rice.kim.api.responsibility.ResponsibilityAction.Builder#build()}
265         * method.  Please see {@link ResponsibilityActionContract} to see what fields are required.
266         *
267         * @return a new builder, not yet in a valid state
268         */
269        public static Builder create() {
270            //there is a lot of required fields - require fields are enforced at build time
271            return new Builder();
272        }
273
274        public static Builder create(ResponsibilityActionContract contract) {
275            if (contract == null) {
276                throw new IllegalArgumentException("contract was null");
277            }
278            Builder builder = create();
279            builder.setPrincipalId(contract.getPrincipalId());
280            builder.setRoleResponsibilityActionId(contract.getRoleResponsibilityActionId());
281            builder.setParallelRoutingGroupingCode(contract.getParallelRoutingGroupingCode());
282            builder.setActionTypeCode(contract.getActionTypeCode());
283            builder.setActionPolicyCode(contract.getActionPolicyCode());
284            builder.setPriorityNumber(contract.getPriorityNumber());
285            builder.setGroupId(contract.getGroupId());
286            builder.setMemberRoleId(contract.getMemberRoleId());
287            builder.setResponsibilityName(contract.getResponsibilityName());
288            builder.setResponsibilityId(contract.getResponsibilityId());
289            builder.setResponsibilityNamespaceCode(contract.getResponsibilityNamespaceCode());
290            builder.setForceAction(contract.isForceAction());
291            builder.setQualifier(contract.getQualifier());
292            final List<DelegateType.Builder> dbs = new ArrayList<DelegateType.Builder>();
293            for (DelegateTypeContract d : contract.getDelegates()) {
294                if (d != null) {
295                    dbs.add(DelegateType.Builder.create(d));
296                }
297            }
298            builder.setDelegates(dbs);
299            builder.setRoleId(contract.getRoleId());
300            return builder;
301        }
302
303        public ResponsibilityAction build() {
304            //validate required fields
305            final boolean requiredSet = (groupId != null ^ principalId != null) &&
306                            memberRoleId != null &&
307                            responsibilityName != null &&
308                            responsibilityId != null &&
309                            responsibilityNamespaceCode != null &&
310                            delegates != null &&
311                            roleId != null;
312
313            if (!requiredSet) {
314                throw new IllegalStateException("all the required fields are not set");
315            }
316            return new ResponsibilityAction(this);
317        }
318
319        @Override
320        public String getPrincipalId() {
321            return this.principalId;
322        }
323
324        @Override
325        public String getRoleResponsibilityActionId() {
326            return this.roleResponsibilityActionId;
327        }
328
329        @Override
330        public String getParallelRoutingGroupingCode() {
331            return this.parallelRoutingGroupingCode;
332        }
333
334        @Override
335        public String getActionTypeCode() {
336            return this.actionTypeCode;
337        }
338
339        @Override
340        public String getActionPolicyCode() {
341            return this.actionPolicyCode;
342        }
343
344        @Override
345        public Integer getPriorityNumber() {
346            return this.priorityNumber;
347        }
348
349        @Override
350        public String getGroupId() {
351            return this.groupId;
352        }
353
354        @Override
355        public String getMemberRoleId() {
356            return this.memberRoleId;
357        }
358
359        @Override
360        public String getResponsibilityName() {
361            return this.responsibilityName;
362        }
363
364        @Override
365        public String getResponsibilityId() {
366            return this.responsibilityId;
367        }
368
369        @Override
370        public String getResponsibilityNamespaceCode() {
371            return this.responsibilityNamespaceCode;
372        }
373
374        @Override
375        public boolean isForceAction() {
376            return this.forceAction;
377        }
378
379        @Override
380        public Map<String, String> getQualifier() {
381            return this.qualifier;
382        }
383
384        @Override
385        public List<DelegateType.Builder> getDelegates() {
386            return Collections.unmodifiableList(this.delegates);
387        }
388
389        @Override
390        public String getRoleId() {
391            return this.roleId;
392        }
393
394        public void setPrincipalId(String principalId) {
395            this.principalId = principalId;
396        }
397
398        public void setRoleResponsibilityActionId(String roleResponsibilityActionId) {
399            this.roleResponsibilityActionId = roleResponsibilityActionId;
400        }
401
402        public void setParallelRoutingGroupingCode(String parallelRoutingGroupingCode) {
403            this.parallelRoutingGroupingCode = parallelRoutingGroupingCode;
404        }
405
406        public void setActionTypeCode(String actionTypeCode) {
407            this.actionTypeCode = actionTypeCode;
408        }
409
410        public void setActionPolicyCode(String actionPolicyCode) {
411            this.actionPolicyCode = actionPolicyCode;
412        }
413
414        public void setPriorityNumber(Integer priorityNumber) {
415            this.priorityNumber = priorityNumber;
416        }
417
418        public void setGroupId(String groupId) {
419            this.groupId = groupId;
420        }
421
422        public void setMemberRoleId(String memberRoleId) {
423            if (StringUtils.isBlank(memberRoleId)) {
424                throw new IllegalArgumentException("memberRoleId is blank");
425            }
426
427            this.memberRoleId = memberRoleId;
428        }
429
430        public void setResponsibilityName(String responsibilityName) {
431            if (StringUtils.isBlank(responsibilityName)) {
432                throw new IllegalArgumentException("responsibilityName is blank");
433            }
434
435            this.responsibilityName = responsibilityName;
436        }
437
438        public void setResponsibilityId(String responsibilityId) {
439            if (StringUtils.isBlank(responsibilityId)) {
440                throw new IllegalArgumentException("responsibilityId is blank");
441            }
442
443            this.responsibilityId = responsibilityId;
444        }
445
446        public void setResponsibilityNamespaceCode(String responsibilityNamespaceCode) {
447            if (StringUtils.isBlank(responsibilityNamespaceCode)) {
448                throw new IllegalArgumentException("responsibilityNamespaceCode is blank");
449            }
450            this.responsibilityNamespaceCode = responsibilityNamespaceCode;
451        }
452
453        public void setForceAction(boolean forceAction) {
454            this.forceAction = forceAction;
455        }
456
457        public void setQualifier(Map<String, String> qualifier) {
458            this.qualifier = (qualifier != null) ? Collections.unmodifiableMap(Maps.newHashMap(qualifier)) : qualifier;
459        }
460
461        public void setDelegates(List<DelegateType.Builder> delegates) {
462            if (delegates == null) {
463                throw new IllegalArgumentException("delegates is null");
464            }
465            this.delegates = new ArrayList<DelegateType.Builder>(delegates);
466        }
467
468        public void setRoleId(String roleId) {
469            if (StringUtils.isBlank(roleId)) {
470                throw new IllegalArgumentException("roleId is blank");
471            }
472            this.roleId = roleId;
473        }
474
475    }
476
477
478    /**
479     * Defines some internal constants used on this class.
480     */
481    static class Constants {
482
483        final static String ROOT_ELEMENT_NAME = "responsibilityAction";
484        final static String TYPE_NAME = "ResponsibilityActionType";
485    }
486
487
488    /**
489     * A private class which exposes constants which define the XML element names to use when this object is marshalled to XML.
490     */
491    static class Elements {
492
493        final static String PRINCIPAL_ID = "principalId";
494        final static String ROLE_RESPONSIBILITY_ACTION_ID = "roleResponsibilityActionId";
495        final static String PARALLEL_ROUTING_GROUPING_CODE = "parallelRoutingGroupingCode";
496        final static String ACTION_TYPE_CODE = "actionTypeCode";
497        final static String ACTION_POLICY_CODE = "actionPolicyCode";
498        final static String PRIORITY_NUMBER = "priorityNumber";
499        final static String GROUP_ID = "groupId";
500        final static String MEMBER_ROLE_ID = "memberRoleId";
501        final static String RESPONSIBILITY_NAME = "responsibilityName";
502        final static String RESPONSIBILITY_ID = "responsibilityId";
503        final static String RESPONSIBILITY_NAMESPACE_CODE = "responsibilityNamespaceCode";
504        final static String FORCE_ACTION = "forceAction";
505        final static String QUALIFIER = "qualifier";
506        final static String DELEGATES = "delegates";
507        final static String DELEGATE = "delegate";
508        final static String ROLE_ID = "roleId";
509
510    }
511
512}