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.rule;
017
018 import org.apache.commons.collections.CollectionUtils;
019 import org.apache.commons.lang.StringUtils;
020 import org.joda.time.DateTime;
021 import org.kuali.rice.core.api.CoreConstants;
022 import org.kuali.rice.core.api.mo.AbstractDataTransferObject;
023 import org.kuali.rice.core.api.mo.ModelBuilder;
024 import org.kuali.rice.kew.api.KewApiConstants;
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.XmlRootElement;
032 import javax.xml.bind.annotation.XmlType;
033 import java.io.Serializable;
034 import java.util.ArrayList;
035 import java.util.Collection;
036 import java.util.Collections;
037 import java.util.HashMap;
038 import java.util.List;
039 import java.util.Map;
040
041 @XmlRootElement(name = Rule.Constants.ROOT_ELEMENT_NAME)
042 @XmlAccessorType(XmlAccessType.NONE)
043 @XmlType(name = Rule.Constants.TYPE_NAME, propOrder = {
044 Rule.Elements.ID,
045 Rule.Elements.NAME,
046 Rule.Elements.RULE_TEMPLATE,
047 Rule.Elements.ACTIVE,
048 Rule.Elements.DESCRIPTION,
049 Rule.Elements.DOC_TYPE_NAME,
050 Rule.Elements.FROM_DATE,
051 Rule.Elements.TO_DATE,
052 Rule.Elements.FORCE_ACTION,
053 Rule.Elements.PREVIOUS_VERSION_ID,
054 Rule.Elements.RULE_RESPONSIBILITIES,
055 Rule.Elements.RULE_EXTENSIONS,
056 Rule.Elements.RULE_TEMPLATE_NAME,
057 Rule.Elements.RULE_EXPRESSION_DEF,
058 CoreConstants.CommonElements.FUTURE_ELEMENTS
059 })
060 public final class Rule
061 extends AbstractDataTransferObject
062 implements RuleContract
063 {
064 @XmlElement(name = Elements.ID, required = false)
065 private final String id;
066 @XmlElement(name = Elements.NAME, required = false)
067 private final String name;
068 @XmlElement(name = Elements.RULE_TEMPLATE, required = false)
069 private final RuleTemplate ruleTemplate;
070 @XmlElement(name = Elements.ACTIVE, required = false)
071 private final boolean active;
072 @XmlElement(name = Elements.DESCRIPTION, required = false)
073 private final String description;
074 @XmlElement(name = Elements.DOC_TYPE_NAME, required = false)
075 private final String docTypeName;
076 @XmlElement(name = Elements.FROM_DATE, required = false)
077 private final DateTime fromDate;
078 @XmlElement(name = Elements.TO_DATE, required = false)
079 private final DateTime toDate;
080 @XmlElement(name = Elements.FORCE_ACTION, required = false)
081 private final boolean forceAction;
082 @XmlElement(name = Elements.PREVIOUS_VERSION_ID, required = false)
083 private final String previousRuleId;
084 @XmlElement(name = Elements.RULE_RESPONSIBILITIES, required = false)
085 private final List<RuleResponsibility> ruleResponsibilities;
086 @XmlElement(name = Elements.RULE_EXTENSIONS, required = false)
087 private final List<RuleExtension> ruleExtensions;
088 @XmlElement(name = Elements.RULE_TEMPLATE_NAME, required = false)
089 private final String ruleTemplateName;
090 @XmlElement(name = Elements.RULE_EXPRESSION_DEF, required = false)
091 private final RuleExpression ruleExpressionDef;
092 @SuppressWarnings("unused")
093 @XmlAnyElement
094 private final Collection<Element> _futureElements = null;
095
096 /**
097 * Private constructor used only by JAXB.
098 *
099 */
100 private Rule() {
101 this.id = null;
102 this.name = null;
103 this.ruleTemplate = null;
104 this.active = false;
105 this.description = null;
106 this.docTypeName = null;
107 this.fromDate = null;
108 this.toDate = null;
109 this.forceAction = false;
110 this.ruleResponsibilities = null;
111 this.ruleExtensions = null;
112 this.ruleTemplateName = null;
113 this.ruleExpressionDef = null;
114 this.previousRuleId = null;
115 }
116
117 private Rule(Builder builder) {
118 this.id = builder.getId();
119 this.name = builder.getName();
120 this.ruleTemplate = builder.getRuleTemplate() == null ? null : builder.getRuleTemplate().build();
121 this.active = builder.isActive();
122 this.description = builder.getDescription();
123 this.docTypeName = builder.getDocTypeName();
124 this.fromDate = builder.getFromDate();
125 this.toDate = builder.getToDate();
126 this.forceAction = builder.isForceAction();
127 if (CollectionUtils.isNotEmpty(builder.getRuleResponsibilities())) {
128 List<RuleResponsibility> responsibilities = new ArrayList<RuleResponsibility>();
129 for (RuleResponsibility.Builder b : builder.getRuleResponsibilities()) {
130 responsibilities.add(b.build());
131 }
132 this.ruleResponsibilities = responsibilities;
133 } else {
134 this.ruleResponsibilities = Collections.emptyList();
135 }
136 if (CollectionUtils.isNotEmpty(builder.getRuleExtensions())) {
137 List<RuleExtension> extensions = new ArrayList<RuleExtension>();
138 for (RuleExtension.Builder b : builder.getRuleExtensions()) {
139 extensions.add(b.build());
140 }
141 this.ruleExtensions = extensions;
142 } else {
143 this.ruleExtensions = Collections.emptyList();
144 }
145 this.ruleTemplateName = builder.getRuleTemplateName();
146 this.ruleExpressionDef = builder.getRuleExpressionDef() == null ? null : builder.getRuleExpressionDef().build();
147 this.previousRuleId = builder.getPreviousRuleId();
148 }
149
150 @Override
151 public String getId() {
152 return this.id;
153 }
154
155 @Override
156 public String getName() {
157 return this.name;
158 }
159
160 @Override
161 public RuleTemplate getRuleTemplate() {
162 return this.ruleTemplate;
163 }
164
165 @Override
166 public boolean isActive() {
167 return this.active;
168 }
169
170 @Override
171 public String getDescription() {
172 return this.description;
173 }
174
175 @Override
176 public String getPreviousRuleId() {
177 return this.previousRuleId;
178 }
179
180 @Override
181 public String getDocTypeName() {
182 return this.docTypeName;
183 }
184
185 @Override
186 public DateTime getFromDate() {
187 return this.fromDate;
188 }
189
190 @Override
191 public DateTime getToDate() {
192 return this.toDate;
193 }
194
195 @Override
196 public boolean isForceAction() {
197 return this.forceAction;
198 }
199
200 @Override
201 public List<RuleResponsibility> getRuleResponsibilities() {
202 return this.ruleResponsibilities;
203 }
204
205 @Override
206 public List<RuleExtension> getRuleExtensions() {
207 return this.ruleExtensions;
208 }
209
210 public Map<String, String> getRuleExtensionMap() {
211 Map<String, String> extensions = new HashMap<String, String>();
212 for (RuleExtension ext : this.getRuleExtensions()) {
213 extensions.putAll(ext.getExtensionValuesMap());
214 }
215 return Collections.unmodifiableMap(extensions);
216 }
217
218 @Override
219 public String getRuleTemplateName() {
220 return this.ruleTemplateName;
221 }
222
223 @Override
224 public RuleExpression getRuleExpressionDef() {
225 return this.ruleExpressionDef;
226 }
227
228
229 /**
230 * A builder which can be used to construct {@link Rule} instances. Enforces the constraints of the {@link RuleContract}.
231 *
232 */
233 public final static class Builder
234 implements Serializable, ModelBuilder, RuleContract
235 {
236 private String id;
237 private String name;
238 private RuleTemplate.Builder ruleTemplate;
239 private boolean active;
240 private String description;
241 private String docTypeName;
242 private DateTime fromDate;
243 private DateTime toDate;
244 private boolean forceAction;
245 private List<RuleResponsibility.Builder> ruleResponsibilities = Collections.<RuleResponsibility.Builder>emptyList();
246 private List<RuleExtension.Builder> ruleExtensions = Collections.emptyList();
247 private String ruleTemplateName;
248 private String previousRuleId;
249 private RuleExpression.Builder ruleExpressionDef;
250
251 private Builder() {
252 setActive(true);
253 }
254
255 public static Builder create() {
256 return new Builder();
257 }
258
259 public static Builder create(RuleContract contract) {
260 if (contract == null) {
261 throw new IllegalArgumentException("contract was null");
262 }
263 Builder builder = create();
264 builder.setId(contract.getId());
265 builder.setName(contract.getName());
266 builder.setRuleTemplate(
267 contract.getRuleTemplate() == null ? null : RuleTemplate.Builder.create(contract.getRuleTemplate()));
268 builder.setActive(contract.isActive());
269 builder.setDescription(contract.getDescription());
270 builder.setDocTypeName(contract.getDocTypeName());
271 builder.setFromDate(contract.getFromDate());
272 builder.setToDate(contract.getToDate());
273 builder.setForceAction(contract.isForceAction());
274 builder.setPreviousRuleId(contract.getPreviousRuleId());
275 if (CollectionUtils.isNotEmpty(contract.getRuleResponsibilities())) {
276 List<RuleResponsibility.Builder> responsibilityBuilders = new ArrayList<RuleResponsibility.Builder>();
277 for (RuleResponsibilityContract c : contract.getRuleResponsibilities()) {
278 responsibilityBuilders.add(RuleResponsibility.Builder.create(c));
279 }
280 builder.setRuleResponsibilities(responsibilityBuilders);
281 } else {
282 builder.setRuleResponsibilities(Collections.<RuleResponsibility.Builder>emptyList());
283 }
284 if (CollectionUtils.isNotEmpty(contract.getRuleExtensions())) {
285 List<RuleExtension.Builder> extensionBuilders = new ArrayList<RuleExtension.Builder>();
286 for (RuleExtensionContract c : contract.getRuleExtensions()) {
287 extensionBuilders.add(RuleExtension.Builder.create(c));
288 }
289 builder.setRuleExtensions(extensionBuilders);
290 } else {
291 builder.setRuleExtensions(Collections.<RuleExtension.Builder>emptyList());
292 }
293 builder.setRuleTemplateName(contract.getRuleTemplateName());
294 if (contract.getRuleExpressionDef() != null) {
295 builder.setRuleExpressionDef(RuleExpression.Builder.create(contract.getRuleExpressionDef()));
296 }
297 return builder;
298 }
299
300 public Rule build() {
301 return new Rule(this);
302 }
303
304 @Override
305 public String getId() {
306 return this.id;
307 }
308
309 @Override
310 public String getName() {
311 return this.name;
312 }
313
314 @Override
315 public RuleTemplate.Builder getRuleTemplate() {
316 return this.ruleTemplate;
317 }
318
319 @Override
320 public boolean isActive() {
321 return this.active;
322 }
323
324 @Override
325 public String getDescription() {
326 return this.description;
327 }
328
329 @Override
330 public String getDocTypeName() {
331 return this.docTypeName;
332 }
333
334 @Override
335 public DateTime getFromDate() {
336 return this.fromDate;
337 }
338
339 @Override
340 public DateTime getToDate() {
341 return this.toDate;
342 }
343
344 @Override
345 public boolean isForceAction() {
346 return this.forceAction;
347 }
348
349 @Override
350 public String getPreviousRuleId() {
351 return this.previousRuleId;
352 }
353
354 @Override
355 public List<RuleResponsibility.Builder> getRuleResponsibilities() {
356 return this.ruleResponsibilities;
357 }
358
359 @Override
360 public List<RuleExtension.Builder> getRuleExtensions() {
361 return this.ruleExtensions;
362 }
363
364 @Override
365 public String getRuleTemplateName() {
366 return this.ruleTemplateName;
367 }
368
369 @Override
370 public RuleExpression.Builder getRuleExpressionDef() {
371 return this.ruleExpressionDef;
372 }
373
374 public void setId(String id) {
375 if (StringUtils.isWhitespace(id)) {
376 throw new IllegalArgumentException("id is blank");
377 }
378 this.id = id;
379 }
380
381 public void setName(String name) {
382 this.name = name;
383 }
384 public void setRuleTemplate(RuleTemplate.Builder ruleTemplate) {
385 this.ruleTemplate = ruleTemplate;
386 }
387
388 public void setActive(boolean active) {
389 this.active = active;
390 }
391
392 public void setDescription(String description) {
393 this.description = description;
394 }
395
396 public void setDocTypeName(String docTypeName) {
397 this.docTypeName = docTypeName;
398 }
399
400 public void setFromDate(DateTime fromDate) {
401 this.fromDate = fromDate;
402 }
403
404 public void setToDate(DateTime toDate) {
405 this.toDate = toDate;
406 }
407
408 public void setForceAction(boolean forceAction) {
409 this.forceAction = forceAction;
410 }
411
412 public void setPreviousRuleId(String previousRuleId) {
413 this.previousRuleId = previousRuleId;
414 }
415
416 public void setRuleResponsibilities(List<RuleResponsibility.Builder> ruleResponsibilities) {
417 this.ruleResponsibilities = Collections.unmodifiableList(ruleResponsibilities);
418 }
419
420 public void setRuleExtensions(List<RuleExtension.Builder> ruleExtensions) {
421 this.ruleExtensions = Collections.unmodifiableList(ruleExtensions);
422 }
423
424 public void setRuleTemplateName(String ruleTemplateName) {
425 this.ruleTemplateName = ruleTemplateName;
426 }
427
428 public void setRuleExpressionDef(RuleExpression.Builder ruleExpressionDef) {
429 this.ruleExpressionDef = ruleExpressionDef;
430 }
431
432 }
433
434
435 /**
436 * Defines some internal constants used on this class.
437 *
438 */
439 static class Constants {
440
441 final static String ROOT_ELEMENT_NAME = "rule";
442 final static String TYPE_NAME = "RuleType";
443
444 }
445
446
447 /**
448 * A private class which exposes constants which define the XML element names to use when this object is marshalled to XML.
449 *
450 */
451 static class Elements {
452 final static String ID = "id";
453 final static String NAME = "name";
454 final static String RULE_TEMPLATE = "ruleTemplate";
455 final static String ACTIVE = "active";
456 final static String DESCRIPTION = "description";
457 final static String DOC_TYPE_NAME = "docTypeName";
458 final static String FROM_DATE = "fromDate";
459 final static String TO_DATE = "toDate";
460 final static String FORCE_ACTION = "forceAction";
461 final static String RULE_RESPONSIBILITIES = "ruleResponsibilities";
462 final static String RULE_EXTENSIONS = "ruleExtensions";
463 final static String RULE_TEMPLATE_NAME = "ruleTemplateName";
464 final static String RULE_EXPRESSION_DEF = "ruleExpressionDef";
465 final static String PREVIOUS_VERSION_ID = "previousRuleId";
466 }
467
468 public static class Cache {
469 public static final String NAME = KewApiConstants.Namespaces.KEW_NAMESPACE_2_0 + "/" + Rule.Constants.TYPE_NAME;
470 }
471 }