001    /**
002     * Copyright 2005-2011 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.kew.api.peopleflow;
017    
018    import org.apache.commons.lang.StringUtils;
019    import org.kuali.rice.core.api.CoreConstants;
020    import org.kuali.rice.core.api.membership.MemberType;
021    import org.kuali.rice.core.api.mo.AbstractDataTransferObject;
022    import org.kuali.rice.core.api.mo.ModelBuilder;
023    import org.kuali.rice.core.api.mo.ModelObjectUtils;
024    import org.kuali.rice.core.api.util.jaxb.MapStringStringAdapter;
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 javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
035    import java.io.Serializable;
036    import java.util.ArrayList;
037    import java.util.Collection;
038    import java.util.HashMap;
039    import java.util.List;
040    import java.util.Map;
041    
042    @XmlRootElement(name = PeopleFlowDefinition.Constants.ROOT_ELEMENT_NAME)
043    @XmlAccessorType(XmlAccessType.NONE)
044    @XmlType(name = PeopleFlowDefinition.Constants.TYPE_NAME, propOrder = {
045            PeopleFlowDefinition.Elements.ID,
046            PeopleFlowDefinition.Elements.NAMESPACE_CODE,
047            PeopleFlowDefinition.Elements.NAME,
048            PeopleFlowDefinition.Elements.TYPE_ID,
049            PeopleFlowDefinition.Elements.DESCRIPTION,
050            PeopleFlowDefinition.Elements.MEMBERS,
051            PeopleFlowDefinition.Elements.ATTRIBUTES,
052            PeopleFlowDefinition.Elements.ACTIVE,
053            CoreConstants.CommonElements.VERSION_NUMBER,
054            CoreConstants.CommonElements.FUTURE_ELEMENTS
055    })
056    public final class PeopleFlowDefinition extends AbstractDataTransferObject implements PeopleFlowContract {
057    
058        @XmlElement(name = Elements.NAME, required = true)
059        private final String name;
060    
061        @XmlElement(name = Elements.ATTRIBUTES, required = false)
062        @XmlJavaTypeAdapter(MapStringStringAdapter.class)
063        private final Map<String, String> attributes;
064    
065        @XmlElement(name = Elements.NAMESPACE_CODE, required = true)
066        private final String namespaceCode;
067    
068        @XmlElement(name = Elements.TYPE_ID, required = false)
069        private final String typeId;
070    
071        @XmlElement(name = Elements.DESCRIPTION, required = false)
072        private final String description;
073    
074        @XmlElementWrapper(name = Elements.MEMBERS, required = false)
075        @XmlElement(name = Elements.MEMBER, required = false)
076        private final List<PeopleFlowMember> members;
077        
078        @XmlElement(name = Elements.ID, required = false)
079        private final String id;
080    
081        @XmlElement(name = Elements.ACTIVE, required = false)
082        private final boolean active;
083    
084        @XmlElement(name = CoreConstants.CommonElements.VERSION_NUMBER, required = false)
085        private final Long versionNumber;
086        
087        @SuppressWarnings("unused")
088        @XmlAnyElement
089        private final Collection<Element> _futureElements = null;
090    
091        /**
092         * Private constructor used only by JAXB.
093         * 
094         */
095        private PeopleFlowDefinition() {
096            this.name = null;
097            this.attributes = null;
098            this.namespaceCode = null;
099            this.typeId = null;
100            this.description = null;
101            this.members = null;
102            this.id = null;
103            this.active = false;
104            this.versionNumber = null;
105        }
106    
107        private PeopleFlowDefinition(Builder builder) {
108            this.name = builder.getName();
109            this.attributes = builder.getAttributes();
110            this.namespaceCode = builder.getNamespaceCode();
111            this.typeId = builder.getTypeId();
112            this.description = builder.getDescription();
113            this.members = ModelObjectUtils.buildImmutableCopy(builder.getMembers());
114            this.id = builder.getId();
115            this.active = builder.isActive();
116            this.versionNumber = builder.getVersionNumber();
117        }
118    
119        @Override
120        public String getName() {
121            return this.name;
122        }
123    
124        @Override
125        public Map<String, String> getAttributes() {
126            return this.attributes;
127        }
128    
129        @Override
130        public String getNamespaceCode() {
131            return this.namespaceCode;
132        }
133    
134        @Override
135        public String getTypeId() {
136            return this.typeId;
137        }
138    
139        @Override
140        public String getDescription() {
141            return this.description;
142        }
143    
144        @Override
145        public List<PeopleFlowMember> getMembers() {
146            return this.members;
147        }
148    
149        @Override
150        public String getId() {
151            return this.id;
152        }
153    
154        @Override
155        public boolean isActive() {
156            return this.active;
157        }
158    
159        @Override
160        public Long getVersionNumber() {
161            return this.versionNumber;
162        }
163    
164        /**
165         * A builder which can be used to construct {@link PeopleFlowDefinition} instances.  Enforces the constraints of the
166         * {@link PeopleFlowContract}.
167         */
168        public final static class Builder implements Serializable, ModelBuilder, PeopleFlowContract {
169    
170            private String name;
171            private Map<String, String> attributes;
172            private String namespaceCode;
173            private String typeId;
174            private String description;
175            private List<PeopleFlowMember.Builder> members;
176            private String id;
177            private boolean active;
178            private Long versionNumber;
179    
180            private Builder(String namespaceCode, String name) {
181                setNamespaceCode(namespaceCode);
182                setName(name);
183                setActive(true);
184                setAttributes(new HashMap<String, String>());
185                setMembers(new ArrayList<PeopleFlowMember.Builder>());
186            }
187    
188            public static Builder create(String namespaceCode, String name) {
189                return new Builder(namespaceCode, name);
190            }
191    
192            public static Builder create(PeopleFlowContract contract) {
193                if (contract == null) {
194                    throw new IllegalArgumentException("contract was null");
195                }
196                Builder builder = create(contract.getNamespaceCode(), contract.getName());
197                if (contract.getAttributes() != null) {
198                    builder.getAttributes().putAll(contract.getAttributes());
199                }
200                builder.setTypeId(contract.getTypeId());
201                builder.setDescription(contract.getDescription());
202                if (contract.getMembers() != null) {
203                    for (PeopleFlowMemberContract member : contract.getMembers()) {
204                        builder.getMembers().add(PeopleFlowMember.Builder.create(member));
205                    }
206                }
207                builder.setId(contract.getId());
208                builder.setActive(contract.isActive());
209                builder.setVersionNumber(contract.getVersionNumber());
210                return builder;
211            }
212    
213            public PeopleFlowDefinition build() {
214                return new PeopleFlowDefinition(this);
215            }
216    
217            @Override
218            public String getName() {
219                return this.name;
220            }
221    
222            @Override
223            public Map<String, String> getAttributes() {
224                return this.attributes;
225            }
226    
227            @Override
228            public String getNamespaceCode() {
229                return this.namespaceCode;
230            }
231    
232            @Override
233            public String getTypeId() {
234                return this.typeId;
235            }
236    
237            @Override
238            public String getDescription() {
239                return this.description;
240            }
241    
242            @Override
243            public List<PeopleFlowMember.Builder> getMembers() {
244                return this.members;
245            }
246    
247            @Override
248            public String getId() {
249                return this.id;
250            }
251    
252            @Override
253            public boolean isActive() {
254                return this.active;
255            }
256    
257            @Override
258            public Long getVersionNumber() {
259                return this.versionNumber;
260            }
261    
262            public void setName(String name) {
263                if (StringUtils.isBlank(name)) {
264                    throw new IllegalArgumentException("name was null or blank");
265                }
266                this.name = name;
267            }
268    
269            public void setAttributes(Map<String, String> attributes) {
270                this.attributes = attributes;
271            }
272    
273            public void setNamespaceCode(String namespaceCode) {
274                if (StringUtils.isBlank(namespaceCode)) {
275                    throw new IllegalArgumentException("namespaceCode was null or blank");
276                }
277                this.namespaceCode = namespaceCode;
278            }
279    
280            public void setTypeId(String typeId) {
281                this.typeId = typeId;
282            }
283    
284            public void setDescription(String description) {
285                this.description = description;
286            }
287    
288            public void setMembers(List<PeopleFlowMember.Builder> members) {
289                this.members = members;
290            }
291    
292            public void setId(String id) {
293                this.id = id;
294            }
295    
296            public void setActive(boolean active) {
297                this.active = active;
298            }
299    
300            public void setVersionNumber(Long versionNumber) {
301                this.versionNumber = versionNumber;
302            }
303    
304            public PeopleFlowMember.Builder addPrincipal(String principalId) {
305                PeopleFlowMember.Builder member = PeopleFlowMember.Builder.create(principalId, MemberType.PRINCIPAL);
306                getMembers().add(member);
307                return member;
308            }
309    
310            public PeopleFlowMember.Builder addGroup(String groupId) {
311                PeopleFlowMember.Builder member = PeopleFlowMember.Builder.create(groupId, MemberType.GROUP);
312                getMembers().add(member);
313                return member;
314            }
315    
316            public PeopleFlowMember.Builder addRole(String roleId) {
317                PeopleFlowMember.Builder member = PeopleFlowMember.Builder.create(roleId, MemberType.ROLE);
318                getMembers().add(member);
319                return member;
320            }
321    
322        }
323    
324        /**
325         * Defines some internal constants used on this class.
326         */
327        static class Constants {
328            final static String ROOT_ELEMENT_NAME = "peopleFlowDefinition";
329            final static String TYPE_NAME = "PeopleFlowDefinitionType";
330        }
331    
332        /**
333         * A private class which exposes constants which define the XML element names to use when this object is marshalled to XML.
334         */
335        static class Elements {
336            final static String NAME = "name";
337            final static String ATTRIBUTES = "attributes";
338            final static String NAMESPACE_CODE = "namespaceCode";
339            final static String TYPE_ID = "typeId";
340            final static String DESCRIPTION = "description";
341            final static String MEMBERS = "members";
342            final static String MEMBER = "member";
343            final static String ID = "id";
344            final static String ACTIVE = "active";
345        }
346    
347    }