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