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.rule;
017
018import java.io.Serializable;
019import java.lang.reflect.Type;
020import java.util.ArrayList;
021import java.util.Collection;
022import java.util.Collections;
023import java.util.List;
024import javax.xml.bind.annotation.XmlAccessType;
025import javax.xml.bind.annotation.XmlAccessorType;
026import javax.xml.bind.annotation.XmlAnyElement;
027import javax.xml.bind.annotation.XmlElement;
028import javax.xml.bind.annotation.XmlElementWrapper;
029import javax.xml.bind.annotation.XmlRootElement;
030import javax.xml.bind.annotation.XmlType;
031
032import org.apache.commons.collections.CollectionUtils;
033import org.apache.commons.lang.ObjectUtils;
034import org.apache.commons.lang.StringUtils;
035import org.apache.commons.lang.math.NumberUtils;
036import org.kuali.rice.core.api.CoreConstants;
037import org.kuali.rice.core.api.mo.AbstractDataTransferObject;
038import org.kuali.rice.core.api.mo.ModelBuilder;
039import org.kuali.rice.kew.api.KewApiConstants;
040import org.w3c.dom.Element;
041
042@XmlRootElement(name = RuleResponsibility.Constants.ROOT_ELEMENT_NAME)
043@XmlAccessorType(XmlAccessType.NONE)
044@XmlType(name = RuleResponsibility.Constants.TYPE_NAME, propOrder = {
045    RuleResponsibility.Elements.ID,
046    RuleResponsibility.Elements.PRIORITY,
047    RuleResponsibility.Elements.RESPONSIBILITY_ID,
048    RuleResponsibility.Elements.ACTION_REQUESTED_CD,
049    RuleResponsibility.Elements.APPROVE_POLICY,
050    RuleResponsibility.Elements.PRINCIPAL_ID,
051    RuleResponsibility.Elements.GROUP_ID,
052    RuleResponsibility.Elements.ROLE_NAME,
053    RuleResponsibility.Elements.DELEGATION_RULES,
054    RuleResponsibility.Elements.USING_ROLE,
055    RuleResponsibility.Elements.USING_GROUP,
056    RuleResponsibility.Elements.USING_PRINCIPAL,
057    CoreConstants.CommonElements.VERSION_NUMBER,
058    CoreConstants.CommonElements.OBJECT_ID,
059    CoreConstants.CommonElements.FUTURE_ELEMENTS
060})
061public final class RuleResponsibility
062    extends AbstractDataTransferObject
063    implements RuleResponsibilityContract
064{
065    @XmlElement(name = Elements.ID, required = false)
066    private final String id;
067
068    @XmlElement(name = Elements.PRIORITY, required = false)
069    private final Integer priority;
070
071    @XmlElement(name = Elements.RESPONSIBILITY_ID, required = true)
072    private final String responsibilityId;
073
074    @XmlElement(name = Elements.ACTION_REQUESTED_CD, required = false)
075    private final String actionRequestedCd;
076
077    @XmlElement(name = Elements.APPROVE_POLICY, required = false)
078    private final String approvePolicy;
079
080    @XmlElement(name = Elements.PRINCIPAL_ID, required = false)
081    private final String principalId;
082
083    @XmlElement(name = Elements.GROUP_ID, required = false)
084    private final String groupId;
085
086    @XmlElement(name = Elements.ROLE_NAME, required = false)
087    private final String roleName;
088
089    @XmlElementWrapper(name = Elements.DELEGATION_RULES, required = false)
090    @XmlElement(name = Elements.DELEGATION_RULE, required = false)
091    private final List<RuleDelegation> delegationRules;
092
093    @XmlElement(name = Elements.USING_ROLE, required = false)
094    private final boolean usingRole;
095
096    @XmlElement(name = Elements.USING_PRINCIPAL, required = false)
097    private final boolean usingPrincipal;
098
099    @XmlElement(name = Elements.USING_GROUP, required = false)
100    private final boolean usingGroup;
101
102    @XmlElement(name = CoreConstants.CommonElements.VERSION_NUMBER, required = false)
103    private final Long versionNumber;
104
105    @XmlElement(name = CoreConstants.CommonElements.OBJECT_ID, required = false)
106    private final String objectId;
107
108    @SuppressWarnings("unused")
109    @XmlAnyElement
110    private final Collection<Element> _futureElements = null;
111
112    /**
113     * Private constructor used only by JAXB.
114     * 
115     */
116    private RuleResponsibility() {
117        this.id = null;
118        this.priority = null;
119        this.responsibilityId = null;
120        this.actionRequestedCd = null;
121        this.approvePolicy = null;
122        this.principalId = null;
123        this.groupId = null;
124        this.roleName = null;
125        this.delegationRules = null;
126        this.usingGroup = false;
127        this.usingPrincipal = false;
128        this.usingRole = false;
129        this.versionNumber = null;
130        this.objectId = null;
131    }
132
133    private RuleResponsibility(Builder builder) {
134        this.id = builder.getId();
135        this.priority = builder.getPriority();
136        this.responsibilityId = builder.getResponsibilityId();
137        this.actionRequestedCd = builder.getActionRequestedCd();
138        this.approvePolicy = builder.getApprovePolicy();
139        this.principalId = builder.getPrincipalId();
140        this.groupId = builder.getGroupId();
141        this.roleName = builder.getRoleName();
142        if (CollectionUtils.isNotEmpty(builder.getDelegationRules())) {
143            List<RuleDelegation> delegationList = new ArrayList<RuleDelegation>();
144            for (RuleDelegation.Builder b : builder.getDelegationRules()) {
145                delegationList.add(b.build());
146            }
147            this.delegationRules = delegationList;
148        } else {
149            this.delegationRules = Collections.emptyList();
150        }
151        this.usingGroup = builder.isUsingGroup();
152        this.usingPrincipal = builder.isUsingPrincipal();
153        this.usingRole = builder.isUsingRole();
154        versionNumber = builder.getVersionNumber();
155        objectId = builder.getObjectId();
156    }
157
158    @Override
159    public String getId() {
160        return this.id;
161    }
162
163    @Override
164    public Integer getPriority() {
165        return this.priority;
166    }
167
168    @Override
169    public String getResponsibilityId() {
170        return this.responsibilityId;
171    }
172
173    @Override
174    public String getActionRequestedCd() {
175        return this.actionRequestedCd;
176    }
177
178    @Override
179    public String getApprovePolicy() {
180        return this.approvePolicy;
181    }
182
183    @Override
184    public String getPrincipalId() {
185        return this.principalId;
186    }
187
188    @Override
189    public String getGroupId() {
190        return this.groupId;
191    }
192
193    @Override
194    public String getRoleName() {
195        return this.roleName;
196    }
197
198    @Override
199    public List<RuleDelegation> getDelegationRules() {
200        return this.delegationRules;
201    }
202
203    @Override
204    public boolean isUsingRole() {
205        return this.usingRole;
206    }
207
208    @Override
209    public boolean isUsingPrincipal() {
210        return this.usingPrincipal;
211    }
212
213    @Override
214    public boolean isUsingGroup() {
215        return this.usingGroup;
216    }
217
218    @Override
219    public Long getVersionNumber() {
220        return versionNumber;
221    }
222
223    @Override
224    public String getObjectId() {
225        return objectId;
226    }
227
228    public String getRoleAttributeName() {
229            return getRoleName().substring(0, getRoleName().indexOf("!"));
230    }
231
232    public String getResolvedRoleName() {
233        if (isUsingRole()) {
234            return getRoleName().substring(getRoleName().indexOf("!") + 1, getRoleName().length());
235        }
236        return null;
237    }
238
239    /**
240     * A builder which can be used to construct {@link RuleResponsibility} instances.  Enforces the constraints of the {@link RuleResponsibilityContract}.
241     * 
242     */
243    public final static class Builder
244        implements Serializable, ModelBuilder, RuleResponsibilityContract
245    {
246        private String id;
247        private Integer priority;
248        private String responsibilityId;
249        private String actionRequestedCd;
250        private String approvePolicy;
251        private String principalId;
252        private String groupId;
253        private String roleName;
254        private List<RuleDelegation.Builder> delegationRules;
255        private boolean usingRole = false;
256        private boolean usingPrincipal = false;
257        private boolean usingGroup = false;
258        private Long versionNumber;
259        private String objectId;
260
261        private Builder() {
262        }
263
264        public static Builder create() {
265            return new Builder();
266        }
267
268        public static Builder create(RuleResponsibilityContract contract) {
269            if (contract == null) {
270                throw new IllegalArgumentException("contract was null");
271            }
272            Builder builder = create();
273            builder.setId(contract.getId());
274            builder.setPriority(contract.getPriority());
275            builder.setResponsibilityId(contract.getResponsibilityId());
276            builder.setActionRequestedCd(contract.getActionRequestedCd());
277            builder.setApprovePolicy(contract.getApprovePolicy());
278            builder.setPrincipalId(contract.getPrincipalId());
279            builder.setGroupId(contract.getGroupId());
280            builder.setRoleName(contract.getRoleName());
281            if (CollectionUtils.isNotEmpty(contract.getDelegationRules())) {
282                List<RuleDelegation.Builder> builders = new ArrayList<RuleDelegation.Builder>();
283                for (RuleDelegationContract delegationContract : contract.getDelegationRules()) {
284                    builders.add(RuleDelegation.Builder.create(delegationContract));
285                }
286                builder.setDelegationRules(builders);
287            } else {
288                builder.setDelegationRules(Collections.<RuleDelegation.Builder>emptyList());
289            }
290            builder.setUsingGroup(contract.isUsingGroup());
291            builder.setUsingPrincipal(contract.isUsingPrincipal());
292            builder.setUsingRole(contract.isUsingRole());
293            builder.setVersionNumber(contract.getVersionNumber());
294            builder.setObjectId(contract.getObjectId());
295            return builder;
296        }
297
298        public RuleResponsibility build() {
299            return new RuleResponsibility(this);
300        }
301
302        @Override
303        public String getId() {
304            return this.id;
305        }
306
307        @Override
308        public Integer getPriority() {
309            return this.priority;
310        }
311
312        @Override
313        public String getResponsibilityId() {
314            return this.responsibilityId;
315        }
316
317        @Override
318        public String getActionRequestedCd() {
319            return this.actionRequestedCd;
320        }
321
322        @Override
323        public String getApprovePolicy() {
324            return this.approvePolicy;
325        }
326
327        @Override
328        public String getPrincipalId() {
329            return this.principalId;
330        }
331
332        @Override
333        public String getGroupId() {
334            return this.groupId;
335        }
336
337        @Override
338        public String getRoleName() {
339            return this.roleName;
340        }
341
342        @Override
343        public List<RuleDelegation.Builder> getDelegationRules() {
344            return this.delegationRules;
345        }
346
347        @Override
348        public boolean isUsingRole() {
349            return this.usingRole;
350        }
351
352        @Override
353        public boolean isUsingPrincipal() {
354            return this.usingPrincipal;
355        }
356
357        @Override
358        public boolean isUsingGroup() {
359            return this.usingGroup;
360        }
361
362        @Override
363        public Long getVersionNumber() {
364            return versionNumber;
365        }
366
367        @Override
368        public String getObjectId() {
369            return objectId;
370        }
371
372        public void setId(String id) {
373            if (StringUtils.isWhitespace(id)) {
374                throw new IllegalArgumentException("id is whitespace");
375            }
376            this.id = id;
377        }
378        public void setPriority(Integer priority) {
379            this.priority = priority;
380        }
381
382        public void setResponsibilityId(String responsibilityId) {
383            this.responsibilityId = responsibilityId;
384        }
385
386        public void setActionRequestedCd(String actionRequestedCd) {
387            this.actionRequestedCd = actionRequestedCd;
388        }
389
390        public void setApprovePolicy(String approvePolicy) {
391            this.approvePolicy = approvePolicy;
392        }
393
394        public void setPrincipalId(String principalId) {
395            this.principalId = principalId;
396        }
397
398        public void setGroupId(String groupId) {
399            this.groupId = groupId;
400        }
401
402        public void setRoleName(String roleName) {
403            this.roleName = roleName;
404        }
405
406        public void setDelegationRules(List<RuleDelegation.Builder> delegationRules) {
407            this.delegationRules = delegationRules;
408        }
409
410        public void setUsingRole(boolean usingRole) {
411            this.usingRole = usingRole;
412        }
413
414        public void setUsingPrincipal(boolean usingPrincipal) {
415            this.usingPrincipal = usingPrincipal;
416        }
417
418        public void setUsingGroup(boolean usingGroup) {
419            this.usingGroup = usingGroup;
420        }
421
422        public void setVersionNumber(Long versionNumber) {
423            this.versionNumber = versionNumber;
424        }
425
426        public void setObjectId(String objectId) {
427            this.objectId = objectId;
428        }
429
430
431    }
432
433    @Override
434    public boolean equals(Object o) {
435        if (o == null) { return false; }
436        if (!(o instanceof RuleResponsibilityContract)) { return false; }
437        RuleResponsibilityContract resp = (RuleResponsibilityContract) o;
438        return StringUtils.equals(getPrincipalId(),  resp.getPrincipalId()) &&
439               StringUtils.equals(getRoleName(), resp.getRoleName()) &&
440               StringUtils.equals(getGroupId(), resp.getGroupId()) &&
441               StringUtils.equals(getActionRequestedCd(), resp.getActionRequestedCd()) &&
442               ObjectUtils.equals(getPriority(), resp.getPriority()) &&
443               StringUtils.equals(getApprovePolicy(), resp.getApprovePolicy());
444    }
445
446    /**
447     * Defines some internal constants used on this class.
448     * 
449     */
450    static class Constants {
451
452        final static String ROOT_ELEMENT_NAME = "ruleResponsibility";
453        final static String TYPE_NAME = "RuleResponsibilityType";
454
455    }
456
457
458    /**
459     * A private class which exposes constants which define the XML element names to use when this object is marshalled to XML.
460     * 
461     */
462    static class Elements {
463        final static String ID = "id";
464        final static String PRIORITY = "priority";
465        final static String RESPONSIBILITY_ID = "responsibilityId";
466        final static String ACTION_REQUESTED_CD = "actionRequestedCd";
467        final static String APPROVE_POLICY = "approvePolicy";
468        final static String PRINCIPAL_ID = "principalId";
469        final static String GROUP_ID = "groupId";
470        final static String ROLE_NAME = "roleName";
471        final static String DELEGATION_RULES = "delegationRules";
472        final static String DELEGATION_RULE = "delegationRule";
473        final static String USING_ROLE = "usingRole";
474        final static String USING_PRINCIPAL = "usingPrincipal";
475        final static String USING_GROUP = "usingGroup";
476    }
477
478    public static class Cache {
479        public static final String NAME = KewApiConstants.Namespaces.KEW_NAMESPACE_2_0 + "/" + RuleResponsibility.Constants.TYPE_NAME;
480    }
481}