View Javadoc

1   /**
2    * Copyright 2005-2012 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.kew.api.rule;
17  
18  import org.apache.commons.collections.CollectionUtils;
19  import org.apache.commons.lang.StringUtils;
20  import org.joda.time.DateTime;
21  import org.kuali.rice.core.api.CoreConstants;
22  import org.kuali.rice.core.api.mo.AbstractDataTransferObject;
23  import org.kuali.rice.core.api.mo.ModelBuilder;
24  import org.kuali.rice.core.api.util.jaxb.DateTimeAdapter;
25  import org.kuali.rice.kew.api.KewApiConstants;
26  import org.w3c.dom.Element;
27  
28  import javax.xml.bind.annotation.XmlAccessType;
29  import javax.xml.bind.annotation.XmlAccessorType;
30  import javax.xml.bind.annotation.XmlAnyElement;
31  import javax.xml.bind.annotation.XmlElement;
32  import javax.xml.bind.annotation.XmlElementWrapper;
33  import javax.xml.bind.annotation.XmlRootElement;
34  import javax.xml.bind.annotation.XmlType;
35  import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
36  import java.io.Serializable;
37  import java.util.ArrayList;
38  import java.util.Collection;
39  import java.util.Collections;
40  import java.util.HashMap;
41  import java.util.List;
42  import java.util.Map;
43  
44  @XmlRootElement(name = Rule.Constants.ROOT_ELEMENT_NAME)
45  @XmlAccessorType(XmlAccessType.NONE)
46  @XmlType(name = Rule.Constants.TYPE_NAME, propOrder = {
47      Rule.Elements.ID,
48      Rule.Elements.NAME,
49      Rule.Elements.RULE_TEMPLATE,
50      Rule.Elements.ACTIVE,
51      Rule.Elements.DESCRIPTION,
52      Rule.Elements.DOC_TYPE_NAME,
53      Rule.Elements.FROM_DATE,
54      Rule.Elements.TO_DATE,
55      Rule.Elements.FORCE_ACTION,
56      Rule.Elements.PREVIOUS_VERSION_ID,
57      Rule.Elements.RULE_RESPONSIBILITIES,
58      Rule.Elements.RULE_EXTENSIONS,
59      Rule.Elements.RULE_TEMPLATE_NAME,
60      Rule.Elements.RULE_EXPRESSION_DEF,
61      Rule.Elements.FROM_DATE_VALUE,
62      Rule.Elements.TO_DATE_VALUE,
63      CoreConstants.CommonElements.FUTURE_ELEMENTS
64  })
65  public final class Rule
66      extends AbstractDataTransferObject
67      implements RuleContract
68  {
69      @XmlElement(name = Elements.ID, required = false)
70      private final String id;
71  
72      @XmlElement(name = Elements.NAME, required = false)
73      private final String name;
74  
75      @XmlElement(name = Elements.RULE_TEMPLATE, required = false)
76      private final RuleTemplate ruleTemplate;
77  
78      @XmlElement(name = Elements.ACTIVE, required = false)
79      private final boolean active;
80  
81      @XmlElement(name = Elements.DESCRIPTION, required = false)
82      private final String description;
83  
84      @XmlElement(name = Elements.DOC_TYPE_NAME, required = false)
85      private final String docTypeName;
86  
87      @Deprecated
88      @XmlElement(name = Elements.FROM_DATE, required = false)
89      private final DateTime fromDate;
90  
91      @Deprecated
92      @XmlElement(name = Elements.TO_DATE, required = false)
93      private final DateTime toDate;
94  
95      @XmlElement(name = Elements.FROM_DATE_VALUE, required = false)
96      @XmlJavaTypeAdapter(DateTimeAdapter.class)
97      private final DateTime fromDateValue;
98  
99      @XmlElement(name = Elements.TO_DATE_VALUE, required = false)
100     @XmlJavaTypeAdapter(DateTimeAdapter.class)
101     private final DateTime toDateValue;
102 
103     @XmlElement(name = Elements.FORCE_ACTION, required = false)
104     private final boolean forceAction;
105 
106     @XmlElement(name = Elements.PREVIOUS_VERSION_ID, required = false)
107     private final String previousRuleId;
108 
109     @XmlElementWrapper(name = Elements.RULE_RESPONSIBILITIES, required = false)
110     @XmlElement(name = Elements.RULE_RESPONSIBILITY, required = false)
111     private final List<RuleResponsibility> ruleResponsibilities;
112 
113     @XmlElementWrapper(name = Elements.RULE_EXTENSIONS, required = false)
114     @XmlElement(name = Elements.RULE_EXTENSION, required = false)
115     private final List<RuleExtension> ruleExtensions;
116 
117     @XmlElement(name = Elements.RULE_TEMPLATE_NAME, required = false)
118     private final String ruleTemplateName;
119 
120     @XmlElement(name = Elements.RULE_EXPRESSION_DEF, required = false)
121     private final RuleExpression ruleExpressionDef;
122 
123     @SuppressWarnings("unused")
124     @XmlAnyElement
125     private final Collection<Element> _futureElements = null;
126 
127     /**
128      * Private constructor used only by JAXB.
129      * 
130      */
131     private Rule() {
132         this.id = null;
133         this.name = null;
134         this.ruleTemplate = null;
135         this.active = false;
136         this.description = null;
137         this.docTypeName = null;
138         this.fromDate = null;
139         this.toDate = null;
140         this.fromDateValue = null;
141         this.toDateValue = null;
142         this.forceAction = false;
143         this.ruleResponsibilities = null;
144         this.ruleExtensions = null;
145         this.ruleTemplateName = null;
146         this.ruleExpressionDef = null;
147         this.previousRuleId = null;
148     }
149 
150     private Rule(Builder builder) {
151         this.id = builder.getId();
152         this.name = builder.getName();
153         this.ruleTemplate = builder.getRuleTemplate() == null ? null : builder.getRuleTemplate().build();
154         this.active = builder.isActive();
155         this.description = builder.getDescription();
156         this.docTypeName = builder.getDocTypeName();
157         this.fromDate = builder.getFromDate();
158         this.toDate = builder.getToDate();
159         this.fromDateValue = builder.getFromDate();
160         this.toDateValue = builder.getToDate();
161         this.forceAction = builder.isForceAction();
162         if (CollectionUtils.isNotEmpty(builder.getRuleResponsibilities())) {
163             List<RuleResponsibility> responsibilities = new ArrayList<RuleResponsibility>();
164             for (RuleResponsibility.Builder b : builder.getRuleResponsibilities()) {
165                 responsibilities.add(b.build());
166             }
167             this.ruleResponsibilities = responsibilities;
168         } else {
169             this.ruleResponsibilities = Collections.emptyList();
170         }
171         if (CollectionUtils.isNotEmpty(builder.getRuleExtensions())) {
172             List<RuleExtension> extensions = new ArrayList<RuleExtension>();
173             for (RuleExtension.Builder b : builder.getRuleExtensions()) {
174                 extensions.add(b.build());
175             }
176             this.ruleExtensions = extensions;
177         } else {
178             this.ruleExtensions = Collections.emptyList();
179         }
180         this.ruleTemplateName = builder.getRuleTemplateName();
181         this.ruleExpressionDef = builder.getRuleExpressionDef() == null ? null : builder.getRuleExpressionDef().build();
182         this.previousRuleId = builder.getPreviousRuleId();
183     }
184 
185     @Override
186     public String getId() {
187         return this.id;
188     }
189 
190     @Override
191     public String getName() {
192         return this.name;
193     }
194 
195     @Override
196     public RuleTemplate getRuleTemplate() {
197         return this.ruleTemplate;
198     }
199 
200     @Override
201     public boolean isActive() {
202         return this.active;
203     }
204 
205     @Override
206     public String getDescription() {
207         return this.description;
208     }
209 
210     @Override
211     public String getPreviousRuleId() {
212         return this.previousRuleId;
213     }
214 
215     @Override
216     public String getDocTypeName() {
217         return this.docTypeName;
218     }
219 
220     @Override
221     public DateTime getFromDate() {
222         return this.fromDateValue == null ? this.fromDate : this.fromDateValue;
223     }
224 
225     @Override
226     public DateTime getToDate() {
227         return this.toDateValue == null ? this.toDate : this.toDateValue;
228     }
229 
230     @Override
231     public boolean isForceAction() {
232         return this.forceAction;
233     }
234 
235     @Override
236     public List<RuleResponsibility> getRuleResponsibilities() {
237         return this.ruleResponsibilities;
238     }
239 
240     @Override
241     public List<RuleExtension> getRuleExtensions() {
242         return this.ruleExtensions;
243     }
244 
245     public Map<String, String> getRuleExtensionMap() {
246         Map<String, String> extensions = new HashMap<String, String>();
247         for (RuleExtension ext : this.getRuleExtensions()) {
248             extensions.putAll(ext.getExtensionValuesMap());
249         }
250         return Collections.unmodifiableMap(extensions);
251     }
252 
253     @Override
254     public String getRuleTemplateName() {
255         return this.ruleTemplateName;
256     }
257 
258     @Override
259     public RuleExpression getRuleExpressionDef() {
260         return this.ruleExpressionDef;
261     }
262 
263 
264     /**
265      * A builder which can be used to construct {@link Rule} instances.  Enforces the constraints of the {@link RuleContract}.
266      * 
267      */
268     public final static class Builder
269         implements Serializable, ModelBuilder, RuleContract
270     {
271         private String id;
272         private String name;
273         private RuleTemplate.Builder ruleTemplate;
274         private boolean active;
275         private String description;
276         private String docTypeName;
277         private DateTime fromDate;
278         private DateTime toDate;
279         private boolean forceAction;
280         private List<RuleResponsibility.Builder> ruleResponsibilities = Collections.<RuleResponsibility.Builder>emptyList();
281         private List<RuleExtension.Builder> ruleExtensions = Collections.emptyList();
282         private String ruleTemplateName;
283         private String previousRuleId;
284         private RuleExpression.Builder ruleExpressionDef;
285 
286         private Builder() {
287             setActive(true);
288         }
289 
290         public static Builder create() {
291             return new Builder();
292         }
293 
294         public static Builder create(RuleContract contract) {
295             if (contract == null) {
296                 throw new IllegalArgumentException("contract was null");
297             }
298             Builder builder = create();
299             builder.setId(contract.getId());
300             builder.setName(contract.getName());
301             builder.setRuleTemplate(
302                     contract.getRuleTemplate() == null ? null : RuleTemplate.Builder.create(contract.getRuleTemplate()));
303             builder.setActive(contract.isActive());
304             builder.setDescription(contract.getDescription());
305             builder.setDocTypeName(contract.getDocTypeName());
306             builder.setFromDate(contract.getFromDate());
307             builder.setToDate(contract.getToDate());
308             builder.setForceAction(contract.isForceAction());
309             builder.setPreviousRuleId(contract.getPreviousRuleId());
310             if (CollectionUtils.isNotEmpty(contract.getRuleResponsibilities())) {
311                 List<RuleResponsibility.Builder> responsibilityBuilders = new ArrayList<RuleResponsibility.Builder>();
312                 for (RuleResponsibilityContract c : contract.getRuleResponsibilities()) {
313                     responsibilityBuilders.add(RuleResponsibility.Builder.create(c));
314                 }
315                 builder.setRuleResponsibilities(responsibilityBuilders);
316             } else {
317                 builder.setRuleResponsibilities(Collections.<RuleResponsibility.Builder>emptyList());
318             }
319             if (CollectionUtils.isNotEmpty(contract.getRuleExtensions())) {
320                 List<RuleExtension.Builder> extensionBuilders = new ArrayList<RuleExtension.Builder>();
321                 for (RuleExtensionContract c : contract.getRuleExtensions()) {
322                     extensionBuilders.add(RuleExtension.Builder.create(c));
323                 }
324                 builder.setRuleExtensions(extensionBuilders);
325             } else {
326                 builder.setRuleExtensions(Collections.<RuleExtension.Builder>emptyList());
327             }
328             builder.setRuleTemplateName(contract.getRuleTemplateName());
329             if (contract.getRuleExpressionDef() != null) {
330                 builder.setRuleExpressionDef(RuleExpression.Builder.create(contract.getRuleExpressionDef()));
331         }
332             return builder;
333         }
334 
335         public Rule build() {
336             return new Rule(this);
337         }
338 
339         @Override
340         public String getId() {
341             return this.id;
342         }
343 
344         @Override
345         public String getName() {
346             return this.name;
347         }
348 
349         @Override
350         public RuleTemplate.Builder getRuleTemplate() {
351             return this.ruleTemplate;
352         }
353 
354         @Override
355         public boolean isActive() {
356             return this.active;
357         }
358 
359         @Override
360         public String getDescription() {
361             return this.description;
362         }
363 
364         @Override
365         public String getDocTypeName() {
366             return this.docTypeName;
367         }
368 
369         @Override
370         public DateTime getFromDate() {
371             return this.fromDate;
372         }
373 
374         @Override
375         public DateTime getToDate() {
376             return this.toDate;
377         }
378 
379         @Override
380         public boolean isForceAction() {
381             return this.forceAction;
382         }
383 
384         @Override
385         public String getPreviousRuleId() {
386             return this.previousRuleId;
387         }
388 
389         @Override
390         public List<RuleResponsibility.Builder> getRuleResponsibilities() {
391             return this.ruleResponsibilities;
392         }
393 
394         @Override
395         public List<RuleExtension.Builder> getRuleExtensions() {
396             return this.ruleExtensions;
397         }
398 
399         @Override
400         public String getRuleTemplateName() {
401             return this.ruleTemplateName;
402         }
403 
404         @Override
405         public RuleExpression.Builder getRuleExpressionDef() {
406             return this.ruleExpressionDef;
407         }
408 
409         public void setId(String id) {
410             if (StringUtils.isWhitespace(id)) {
411                 throw new IllegalArgumentException("id is blank");
412             }
413             this.id  = id;
414         }
415 
416         public void setName(String name) {
417             this.name = name;
418         }
419         public void setRuleTemplate(RuleTemplate.Builder ruleTemplate) {
420             this.ruleTemplate = ruleTemplate;
421         }
422 
423         public void setActive(boolean active) {
424             this.active = active;
425         }
426 
427         public void setDescription(String description) {
428             this.description = description;
429         }
430 
431         public void setDocTypeName(String docTypeName) {
432             this.docTypeName = docTypeName;
433         }
434 
435         public void setFromDate(DateTime fromDate) {
436             this.fromDate = fromDate;
437         }
438 
439         public void setToDate(DateTime toDate) {
440             this.toDate = toDate;
441         }
442 
443         public void setForceAction(boolean forceAction) {
444             this.forceAction = forceAction;
445         }
446 
447         public void setPreviousRuleId(String previousRuleId) {
448             this.previousRuleId = previousRuleId;
449         }
450 
451         public void setRuleResponsibilities(List<RuleResponsibility.Builder> ruleResponsibilities) {
452             this.ruleResponsibilities = Collections.unmodifiableList(ruleResponsibilities);
453         }
454 
455         public void setRuleExtensions(List<RuleExtension.Builder> ruleExtensions) {
456             this.ruleExtensions = Collections.unmodifiableList(ruleExtensions);
457         }
458 
459         public void setRuleTemplateName(String ruleTemplateName) {
460             this.ruleTemplateName = ruleTemplateName;
461         }
462 
463         public void setRuleExpressionDef(RuleExpression.Builder ruleExpressionDef) {
464             this.ruleExpressionDef = ruleExpressionDef;
465         }
466 
467     }
468 
469 
470     /**
471      * Defines some internal constants used on this class.
472      * 
473      */
474     static class Constants {
475 
476         final static String ROOT_ELEMENT_NAME = "rule";
477         final static String TYPE_NAME = "RuleType";
478 
479     }
480 
481 
482     /**
483      * A private class which exposes constants which define the XML element names to use when this object is marshalled to XML.
484      * 
485      */
486     static class Elements {
487         final static String ID = "id";
488         final static String NAME = "name";
489         final static String RULE_TEMPLATE = "ruleTemplate";
490         final static String ACTIVE = "active";
491         final static String DESCRIPTION = "description";
492         final static String DOC_TYPE_NAME = "docTypeName";
493         final static String FROM_DATE = "fromDate";
494         final static String TO_DATE = "toDate";
495         final static String FROM_DATE_VALUE = "fromDateValue";
496         final static String TO_DATE_VALUE = "toDateValue";
497         final static String FORCE_ACTION = "forceAction";
498         final static String RULE_RESPONSIBILITIES = "ruleResponsibilities";
499         final static String RULE_RESPONSIBILITY = "ruleResponsibility";
500         final static String RULE_EXTENSIONS = "ruleExtensions";
501         final static String RULE_EXTENSION = "ruleExtension";
502         final static String RULE_TEMPLATE_NAME = "ruleTemplateName";
503         final static String RULE_EXPRESSION_DEF = "ruleExpressionDef";
504         final static String PREVIOUS_VERSION_ID = "previousRuleId";
505     }
506 
507     public static class Cache {
508         public static final String NAME = KewApiConstants.Namespaces.KEW_NAMESPACE_2_0 + "/" + Rule.Constants.TYPE_NAME;
509     }
510 }