001 /**
002 * Copyright 2005-2012 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 Builder builder = createCopy(contract);
194 builder.setVersionNumber(contract.getVersionNumber());
195 if (contract.getMembers() != null) {
196 for (PeopleFlowMemberContract member : contract.getMembers()) {
197 builder.getMembers().add(PeopleFlowMember.Builder.create(member));
198 }
199 }
200 return builder;
201 }
202
203 private static Builder createCopy(PeopleFlowContract contract) {
204 if (contract == null) {
205 throw new IllegalArgumentException("contract was null");
206 }
207 Builder builder = create(contract.getNamespaceCode(), contract.getName());
208 if (contract.getAttributes() != null) {
209 builder.getAttributes().putAll(contract.getAttributes());
210 }
211 if (StringUtils.isEmpty(contract.getTypeId())) {
212 // type_id is a foreign key, it needs to be either null or a real value, not empty String to avoid SQL Exception
213 builder.setTypeId(null);
214 } else {
215 builder.setTypeId(contract.getTypeId());
216 }
217 builder.setDescription(contract.getDescription());
218 builder.setId(contract.getId());
219 builder.setActive(contract.isActive());
220 return builder;
221 }
222
223 public static Builder createMaintenanceCopy(PeopleFlowContract contract) {
224 Builder builder = createCopy(contract);
225 if (contract.getMembers() != null) {
226 for (PeopleFlowMemberContract member : contract.getMembers()) {
227 builder.getMembers().add(PeopleFlowMember.Builder.createCopy(member));
228 }
229 }
230 return builder;
231 }
232
233 public PeopleFlowDefinition build() {
234 return new PeopleFlowDefinition(this);
235 }
236
237 @Override
238 public String getName() {
239 return this.name;
240 }
241
242 @Override
243 public Map<String, String> getAttributes() {
244 return this.attributes;
245 }
246
247 @Override
248 public String getNamespaceCode() {
249 return this.namespaceCode;
250 }
251
252 @Override
253 public String getTypeId() {
254 return this.typeId;
255 }
256
257 @Override
258 public String getDescription() {
259 return this.description;
260 }
261
262 @Override
263 public List<PeopleFlowMember.Builder> getMembers() {
264 return this.members;
265 }
266
267 @Override
268 public String getId() {
269 return this.id;
270 }
271
272 @Override
273 public boolean isActive() {
274 return this.active;
275 }
276
277 @Override
278 public Long getVersionNumber() {
279 return this.versionNumber;
280 }
281
282 public void setName(String name) {
283 if (StringUtils.isBlank(name)) {
284 throw new IllegalArgumentException("name was null or blank");
285 }
286 this.name = name;
287 }
288
289 public void setAttributes(Map<String, String> attributes) {
290 this.attributes = attributes;
291 }
292
293 public void setNamespaceCode(String namespaceCode) {
294 if (StringUtils.isBlank(namespaceCode)) {
295 throw new IllegalArgumentException("namespaceCode was null or blank");
296 }
297 this.namespaceCode = namespaceCode;
298 }
299
300 public void setTypeId(String typeId) {
301 this.typeId = typeId;
302 }
303
304 public void setDescription(String description) {
305 this.description = description;
306 }
307
308 public void setMembers(List<PeopleFlowMember.Builder> members) {
309 this.members = members;
310 }
311
312 public void setId(String id) {
313 this.id = id;
314 }
315
316 public void setActive(boolean active) {
317 this.active = active;
318 }
319
320 public void setVersionNumber(Long versionNumber) {
321 this.versionNumber = versionNumber;
322 }
323
324 public PeopleFlowMember.Builder addPrincipal(String principalId) {
325 PeopleFlowMember.Builder member = PeopleFlowMember.Builder.create(principalId, MemberType.PRINCIPAL);
326 getMembers().add(member);
327 return member;
328 }
329
330 public PeopleFlowMember.Builder addGroup(String groupId) {
331 PeopleFlowMember.Builder member = PeopleFlowMember.Builder.create(groupId, MemberType.GROUP);
332 getMembers().add(member);
333 return member;
334 }
335
336 public PeopleFlowMember.Builder addRole(String roleId) {
337 PeopleFlowMember.Builder member = PeopleFlowMember.Builder.create(roleId, MemberType.ROLE);
338 getMembers().add(member);
339 return member;
340 }
341
342 }
343
344 /**
345 * Defines some internal constants used on this class.
346 */
347 static class Constants {
348 final static String ROOT_ELEMENT_NAME = "peopleFlowDefinition";
349 final static String TYPE_NAME = "PeopleFlowDefinitionType";
350 }
351
352 /**
353 * A private class which exposes constants which define the XML element names to use when this object is marshalled to XML.
354 */
355 static class Elements {
356 final static String NAME = "name";
357 final static String ATTRIBUTES = "attributes";
358 final static String NAMESPACE_CODE = "namespaceCode";
359 final static String TYPE_ID = "typeId";
360 final static String DESCRIPTION = "description";
361 final static String MEMBERS = "members";
362 final static String MEMBER = "member";
363 final static String ID = "id";
364 final static String ACTIVE = "active";
365 }
366
367 }