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.kew.api.KewApiConstants;
25  import org.w3c.dom.Element;
26  
27  import javax.xml.bind.annotation.XmlAccessType;
28  import javax.xml.bind.annotation.XmlAccessorType;
29  import javax.xml.bind.annotation.XmlAnyElement;
30  import javax.xml.bind.annotation.XmlElement;
31  import javax.xml.bind.annotation.XmlElementWrapper;
32  import javax.xml.bind.annotation.XmlRootElement;
33  import javax.xml.bind.annotation.XmlType;
34  import java.io.Serializable;
35  import java.util.ArrayList;
36  import java.util.Collection;
37  import java.util.Collections;
38  import java.util.HashMap;
39  import java.util.List;
40  import java.util.Map;
41  
42  @XmlRootElement(name = Rule.Constants.ROOT_ELEMENT_NAME)
43  @XmlAccessorType(XmlAccessType.NONE)
44  @XmlType(name = Rule.Constants.TYPE_NAME, propOrder = {
45      Rule.Elements.ID,
46      Rule.Elements.NAME,
47      Rule.Elements.RULE_TEMPLATE,
48      Rule.Elements.ACTIVE,
49      Rule.Elements.DESCRIPTION,
50      Rule.Elements.DOC_TYPE_NAME,
51      Rule.Elements.FROM_DATE,
52      Rule.Elements.TO_DATE,
53      Rule.Elements.FORCE_ACTION,
54      Rule.Elements.PREVIOUS_VERSION_ID,
55      Rule.Elements.RULE_RESPONSIBILITIES,
56      Rule.Elements.RULE_EXTENSIONS,
57      Rule.Elements.RULE_TEMPLATE_NAME,
58      Rule.Elements.RULE_EXPRESSION_DEF,
59      CoreConstants.CommonElements.FUTURE_ELEMENTS
60  })
61  public final class Rule
62      extends AbstractDataTransferObject
63      implements RuleContract
64  {
65      @XmlElement(name = Elements.ID, required = false)
66      private final String id;
67  
68      @XmlElement(name = Elements.NAME, required = false)
69      private final String name;
70  
71      @XmlElement(name = Elements.RULE_TEMPLATE, required = false)
72      private final RuleTemplate ruleTemplate;
73  
74      @XmlElement(name = Elements.ACTIVE, required = false)
75      private final boolean active;
76  
77      @XmlElement(name = Elements.DESCRIPTION, required = false)
78      private final String description;
79  
80      @XmlElement(name = Elements.DOC_TYPE_NAME, required = false)
81      private final String docTypeName;
82  
83      @XmlElement(name = Elements.FROM_DATE, required = false)
84      private final DateTime fromDate;
85  
86      @XmlElement(name = Elements.TO_DATE, required = false)
87      private final DateTime toDate;
88  
89      @XmlElement(name = Elements.FORCE_ACTION, required = false)
90      private final boolean forceAction;
91  
92      @XmlElement(name = Elements.PREVIOUS_VERSION_ID, required = false)
93      private final String previousRuleId;
94  
95      @XmlElementWrapper(name = Elements.RULE_RESPONSIBILITIES, required = false)
96      @XmlElement(name = Elements.RULE_RESPONSIBILITY, required = false)
97      private final List<RuleResponsibility> ruleResponsibilities;
98  
99      @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 }