1 package org.kuali.rice.krms.api.repository.rule;
2
3 import org.apache.commons.lang.StringUtils;
4 import org.kuali.rice.core.api.CoreConstants;
5 import org.kuali.rice.core.api.mo.AbstractDataTransferObject;
6 import org.kuali.rice.core.api.mo.ModelBuilder;
7 import org.kuali.rice.core.api.util.jaxb.MapStringStringAdapter;
8 import org.kuali.rice.krms.api.repository.action.ActionDefinition;
9 import org.kuali.rice.krms.api.repository.action.ActionDefinitionContract;
10 import org.kuali.rice.krms.api.repository.proposition.PropositionDefinition;
11
12 import javax.xml.bind.annotation.XmlAccessType;
13 import javax.xml.bind.annotation.XmlAccessorType;
14 import javax.xml.bind.annotation.XmlAnyElement;
15 import javax.xml.bind.annotation.XmlElement;
16 import javax.xml.bind.annotation.XmlElementWrapper;
17 import javax.xml.bind.annotation.XmlRootElement;
18 import javax.xml.bind.annotation.XmlTransient;
19 import javax.xml.bind.annotation.XmlType;
20 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
21 import java.io.Serializable;
22 import java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.Collections;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Map;
28
29
30
31
32
33
34
35
36 @XmlRootElement(name = RuleDefinition.Constants.ROOT_ELEMENT_NAME)
37 @XmlAccessorType(XmlAccessType.NONE)
38 @XmlType(name = RuleDefinition.Constants.TYPE_NAME, propOrder = {
39 RuleDefinition.Elements.ID,
40 RuleDefinition.Elements.NAME,
41 RuleDefinition.Elements.NAMESPACE,
42 RuleDefinition.Elements.DESCRIPTION,
43 RuleDefinition.Elements.TYPE_ID,
44 RuleDefinition.Elements.PROPOSITION,
45 RuleDefinition.Elements.ACTIONS,
46 RuleDefinition.Elements.ATTRIBUTES,
47 CoreConstants.CommonElements.VERSION_NUMBER,
48 CoreConstants.CommonElements.FUTURE_ELEMENTS
49 })
50 public final class RuleDefinition extends AbstractDataTransferObject implements RuleDefinitionContract {
51 private static final long serialVersionUID = 2783959459503209577L;
52
53 @XmlElement(name = Elements.ID, required=true)
54 private String id;
55 @XmlElement(name = Elements.NAME, required=true)
56 private String name;
57 @XmlElement(name = Elements.NAMESPACE, required=true)
58 private String namespace;
59 @XmlElement(name = Elements.DESCRIPTION, required=false)
60 private String description;
61 @XmlElement(name = Elements.TYPE_ID, required=true)
62 private String typeId;
63 @XmlElement(name = Elements.PROPOSITION, required=true)
64 private PropositionDefinition proposition;
65
66 @XmlElementWrapper(name = Elements.ACTIONS)
67 @XmlElement(name = Elements.ACTION, required=false)
68 private List<ActionDefinition> actions;
69
70 @XmlElement(name = Elements.ATTRIBUTES, required = false)
71 @XmlJavaTypeAdapter(value = MapStringStringAdapter.class)
72 private final Map<String, String> attributes;
73
74 @XmlElement(name = CoreConstants.CommonElements.VERSION_NUMBER, required = false)
75 private final Long versionNumber;
76
77 @SuppressWarnings("unused")
78 @XmlAnyElement
79 private final Collection<org.w3c.dom.Element> _futureElements = null;
80
81 @XmlTransient
82 private String propId;
83
84
85
86
87
88 private RuleDefinition() {
89 this.id = null;
90 this.name = null;
91 this.namespace = null;
92 this.typeId = null;
93 this.propId = null;
94 this.proposition = null;
95 this.actions = null;
96 this.attributes = null;
97 this.versionNumber = null;
98 }
99
100
101
102
103
104
105
106 private RuleDefinition(Builder builder) {
107 this.id = builder.getId();
108 this.name = builder.getName();
109 this.namespace = builder.getNamespace();
110 this.typeId = builder.getTypeId();
111 this.propId = builder.getPropId();
112
113 if (builder.getProposition() != null) {
114 this.proposition = builder.getProposition().build();
115 }
116
117 List<ActionDefinition> actionList = new ArrayList<ActionDefinition> ();
118 if (builder.getActions() != null){
119 for (ActionDefinition.Builder b : builder.actions){
120 actionList.add(b.build());
121 }
122 this.actions = Collections.unmodifiableList(actionList);
123 }
124 if (builder.attributes != null){
125 this.attributes = Collections.unmodifiableMap(builder.getAttributes());
126 } else {
127 this.attributes = null;
128 }
129 this.versionNumber = builder.getVersionNumber();
130 }
131
132 @Override
133 public String getId() {
134 return this.id;
135 }
136
137 @Override
138 public String getName() {
139 return this.name;
140 }
141
142 public String getDescription() {
143 return this.description;
144 }
145
146 @Override
147 public String getNamespace() {
148 return this.namespace;
149 }
150
151 @Override
152 public String getTypeId() {
153 return this.typeId;
154 }
155
156 @Override
157 public String getPropId(){
158 return this.propId;
159 }
160
161 @Override
162 public PropositionDefinition getProposition(){
163 return this.proposition;
164 }
165
166 @Override
167 public List<ActionDefinition> getActions(){
168 return this.actions;
169 }
170
171 @Override
172 public Map<String, String> getAttributes() {
173 return this.attributes;
174 }
175
176 @Override
177 public Long getVersionNumber() {
178 return versionNumber;
179 }
180
181
182
183
184 public static class Builder implements RuleDefinitionContract, ModelBuilder, Serializable {
185 private static final long serialVersionUID = -7850514191699945347L;
186
187 private String id;
188 private String name;
189 private String description;
190 private String namespace;
191 private String typeId;
192 private String propId;
193 private PropositionDefinition.Builder proposition;
194 private List<ActionDefinition.Builder> actions;
195 private Map<String, String> attributes;
196 private Long versionNumber;
197
198
199
200
201 private Builder(String ruleId, String name, String namespace, String typeId, String propId) {
202 setId(ruleId);
203 setName(name);
204 setNamespace(namespace);
205 setTypeId(typeId);
206 setPropId(propId);
207 setAttributes(new HashMap<String, String>());
208 }
209
210 public static Builder create(String ruleId, String name, String namespace, String typeId, String propId){
211 return new Builder(ruleId, name, namespace, typeId, propId);
212 }
213
214
215
216
217
218
219
220 public static Builder create(RuleDefinitionContract contract) {
221 if (contract == null) {
222 throw new IllegalArgumentException("contract is null");
223 }
224
225 List <ActionDefinition.Builder> actionList = new ArrayList<ActionDefinition.Builder>();
226 if (contract.getActions() != null){
227 for (ActionDefinitionContract actionContract : contract.getActions()){
228 ActionDefinition.Builder actBuilder = ActionDefinition.Builder.create(actionContract);
229 actionList.add(actBuilder);
230 }
231 }
232
233 Builder builder = new Builder(contract.getId(), contract.getName(),
234 contract.getNamespace(), contract.getTypeId(), contract.getPropId());
235 if (contract.getProposition() != null) {
236 builder.setProposition(PropositionDefinition.Builder.create(contract.getProposition()));
237 }
238 if (contract.getAttributes() != null){
239 builder.setAttributes(new HashMap<String, String>(contract.getAttributes()));
240 }
241 builder.setActions(actionList);
242 builder.setVersionNumber(contract.getVersionNumber());
243 builder.setDescription(contract.getDescription());
244 return builder;
245 }
246
247
248
249
250
251
252
253
254 public void setId(String ruleId) {
255 if (ruleId != null && StringUtils.isBlank(ruleId)) {
256 throw new IllegalArgumentException("rule ID must be null or else non-blank");
257 }
258 this.id = ruleId;
259 }
260
261 public void setName(String name) {
262 if (StringUtils.isBlank(name)) {
263 throw new IllegalArgumentException("name is blank");
264 }
265 this.name = name;
266 }
267
268 public void setDescription(String description) {
269 if (description != null && StringUtils.isBlank(description)) {
270 throw new IllegalArgumentException("description is non-null but is blank");
271 }
272 this.description = description;
273 }
274
275 public void setNamespace(String namespace) {
276 if (StringUtils.isBlank(namespace)) {
277 throw new IllegalArgumentException("namespace is blank");
278 }
279 this.namespace = namespace;
280 }
281
282 public void setTypeId(String typeId) {
283 if (StringUtils.isBlank(typeId)) {
284 throw new IllegalArgumentException("KRMS type id is blank");
285 }
286 this.typeId = typeId;
287 }
288
289 public void setPropId(String propId) {
290 if (propId != null && StringUtils.isBlank(propId)) {
291 throw new IllegalArgumentException("propId must be null or non-blank");
292 }
293 this.propId = propId;
294 }
295
296 public void setProposition(PropositionDefinition.Builder prop) {
297 this.proposition = prop;
298 this.setPropId(prop.getId());
299 }
300
301 public void setActions(List<ActionDefinition.Builder> actions) {
302 if (actions == null){
303 this.actions = Collections.unmodifiableList(new ArrayList<ActionDefinition.Builder>());
304 return;
305 }
306 this.actions = Collections.unmodifiableList(actions);
307 }
308
309 public void setAttributes(Map<String, String> attributes){
310 if (attributes == null){
311 this.attributes = Collections.emptyMap();
312 }
313 this.attributes = Collections.unmodifiableMap(attributes);
314 }
315
316 public void setVersionNumber(Long versionNumber){
317 this.versionNumber = versionNumber;
318 }
319
320 @Override
321 public String getId() {
322 return id;
323 }
324
325 @Override
326 public String getName() {
327 return name;
328 }
329
330 @Override
331 public String getDescription() {
332 return description;
333 }
334
335 @Override
336 public String getNamespace() {
337 return namespace;
338 }
339
340 @Override
341 public String getTypeId() {
342 return typeId;
343 }
344
345 @Override
346 public String getPropId() {
347 return propId;
348 }
349
350 @Override
351 public PropositionDefinition.Builder getProposition() {
352 return proposition;
353 }
354
355 @Override
356 public List<ActionDefinition.Builder> getActions(){
357 return actions;
358 }
359 @Override
360 public Map<String, String> getAttributes() {
361 return attributes;
362 }
363
364 @Override
365 public Long getVersionNumber() {
366 return versionNumber;
367 }
368
369
370
371
372
373
374 @Override
375 public RuleDefinition build() {
376 return new RuleDefinition(this);
377 }
378
379 }
380
381
382
383
384 public static class Constants {
385 final static String ROOT_ELEMENT_NAME = "rule";
386 final static String TYPE_NAME = "RuleType";
387 }
388
389
390
391
392
393 public static class Elements {
394 final static String ID = "id";
395 final static String NAME = "name";
396 final static String DESCRIPTION = "description";
397 final static String NAMESPACE = "namespace";
398 final static String TYPE_ID = "typeId";
399 final static String PROPOSITION = "proposition";
400 final static String ACTIONS = "actions";
401 final static String ACTION = "action";
402 final static String ATTRIBUTES = "attributes";
403 }
404
405 }