View Javadoc
1   /**
2    * Copyright 2005-2014 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.krms.impl.repository;
17  
18  import org.apache.commons.collections.CollectionUtils;
19  import org.apache.commons.lang.StringUtils;
20  import org.kuali.rice.core.api.mo.common.Versioned;
21  import org.kuali.rice.core.api.util.io.SerializationUtils;
22  import org.kuali.rice.krad.data.jpa.PortableSequenceGenerator;
23  import org.kuali.rice.krms.api.repository.agenda.AgendaDefinitionContract;
24  import org.kuali.rice.krms.api.repository.agenda.AgendaItemDefinition;
25  import org.kuali.rice.krms.api.repository.agenda.AgendaItemDefinitionContract;
26  import org.kuali.rice.krms.api.repository.type.KrmsTypeDefinition;
27  
28  import javax.persistence.CascadeType;
29  import javax.persistence.Column;
30  import javax.persistence.Entity;
31  import javax.persistence.FetchType;
32  import javax.persistence.GeneratedValue;
33  import javax.persistence.Id;
34  import javax.persistence.JoinColumn;
35  import javax.persistence.ManyToOne;
36  import javax.persistence.Table;
37  import javax.persistence.Version;
38  import java.io.Serializable;
39  import java.util.ArrayList;
40  import java.util.List;
41  import java.util.Map;
42  
43  /**
44   * Agenda Item business object
45   *
46   * @author Kuali Rice Team (rice.collab@kuali.org)
47   *
48   */
49  @Entity
50  @Table(name = "KRMS_AGENDA_ITM_T")
51  public class AgendaItemBo implements AgendaItemDefinitionContract, Versioned, Serializable {
52  
53      private static final long serialVersionUID = 1L;
54  
55      public static final String COPY_OF_TEXT = "Copy of ";
56  
57      public static final String AGENDA_ITEM_SEQ_NAME = "KRMS_AGENDA_ITM_S";
58      static final RepositoryBoIncrementer agendaItemIdIncrementer = new RepositoryBoIncrementer(AGENDA_ITEM_SEQ_NAME);
59  
60      @PortableSequenceGenerator(name = AGENDA_ITEM_SEQ_NAME)
61      @GeneratedValue(generator = AGENDA_ITEM_SEQ_NAME)
62      @Id
63      @Column(name = "AGENDA_ITM_ID")
64      private String id;
65  
66      @Column(name = "AGENDA_ID")
67      private String agendaId;
68  
69      @Column(name = "RULE_ID")
70      private String ruleId;
71  
72      @Column(name = "SUB_AGENDA_ID")
73      private String subAgendaId;
74  
75      @Column(name = "WHEN_TRUE")
76      private String whenTrueId;
77  
78      @Column(name = "WHEN_FALSE")
79      private String whenFalseId;
80  
81      @Column(name = "ALWAYS")
82      private String alwaysId;
83  
84      @ManyToOne(targetEntity = RuleBo.class, fetch = FetchType.LAZY, cascade = { CascadeType.REFRESH })
85      @JoinColumn(name = "RULE_ID", referencedColumnName = "RULE_ID", insertable = false, updatable = false)
86      private RuleBo rule;
87  
88      @Column(name = "VER_NBR")
89      @Version
90      private Long versionNumber;
91  
92      @ManyToOne(targetEntity = AgendaItemBo.class, cascade = { CascadeType.REFRESH })
93      @JoinColumn(name = "WHEN_TRUE", referencedColumnName = "AGENDA_ITM_ID", insertable = false, updatable = false)
94      private AgendaItemBo whenTrue;
95  
96      @ManyToOne(targetEntity = AgendaItemBo.class, cascade = { CascadeType.REFRESH })
97      @JoinColumn(name = "WHEN_FALSE", referencedColumnName = "AGENDA_ITM_ID", insertable = false, updatable = false)
98      private AgendaItemBo whenFalse;
99  
100     @ManyToOne(targetEntity = AgendaItemBo.class, cascade = { CascadeType.REFRESH })
101     @JoinColumn(name = "ALWAYS", referencedColumnName = "AGENDA_ITM_ID", insertable = false, updatable = false)
102     private AgendaItemBo always;
103 
104     public String getUl(AgendaItemBo firstItem) {
105         return ("<ul>" + getUlHelper(firstItem) + "</ul>");
106     }
107 
108     public String getUlHelper(AgendaItemBo item) {
109         StringBuilder sb = new StringBuilder();
110         sb.append("<li>" + ruleId + "</li>");
111 
112         if (whenTrue != null) {
113             sb.append("<ul><li>when true</li><ul>");
114             sb.append(getUlHelper(whenTrue));
115             sb.append("</ul></ul>");
116         }
117         if (whenFalse != null) {
118             sb.append("<ul><li>when false</li><ul>");
119             sb.append(getUlHelper(whenFalse));
120             sb.append("</ul></ul>");
121         }
122         if (always != null) {
123             sb.append(getUlHelper(always));
124         }
125 
126         return sb.toString();
127     }
128 
129     public String getRuleText() {
130         StringBuilder resultBuilder = new StringBuilder();
131         if (getRule() != null) {
132             if (StringUtils.isBlank(getRule().getName())) {
133                 resultBuilder.append("- unnamed rule -");
134             } else {
135                 resultBuilder.append(getRule().getName());
136             }
137             if (!StringUtils.isBlank(getRule().getDescription())) {
138                 resultBuilder.append(": ");
139                 resultBuilder.append(getRule().getDescription());
140             }
141 
142             // add a description of the action configured on the rule, if there is one  
143             if (!CollectionUtils.isEmpty(getRule().getActions())) {
144                 resultBuilder.append("   [");
145                 ActionBo action = getRule().getActions().get(0);
146                 KrmsTypeDefinition krmsTypeDefn = KrmsRepositoryServiceLocator.getKrmsTypeRepositoryService().getTypeById(action.getTypeId());
147                 resultBuilder.append(krmsTypeDefn.getName());
148                 resultBuilder.append(": ");
149                 resultBuilder.append(action.getName());
150 
151                 if (getRule().getActions().size() > 1) {
152                     resultBuilder.append(" ... ");
153                 }
154 
155                 resultBuilder.append("]");
156             }
157         } else {
158             throw new IllegalStateException();
159         }
160 
161         return resultBuilder.toString();
162     }
163 
164     public List<AgendaItemBo> getAlwaysList() {
165         List<AgendaItemBo> results = new ArrayList<AgendaItemBo>();
166         AgendaItemBo currentNode = this;
167 
168         while (currentNode.always != null) {
169             results.add(currentNode.always);
170             currentNode = currentNode.always;
171         }
172 
173         return results;
174     }
175 
176     /**
177      * @return the id
178      */
179     public String getId() {
180         return this.id;
181     }
182 
183     /**
184      * @param id the id to set
185      */
186     public void setId(String id) {
187         this.id = id;
188     }
189 
190     /**
191      * @return the agendaId
192      */
193     public String getAgendaId() {
194         return this.agendaId;
195     }
196 
197     /**
198      * @param agendaId the agendaId to set
199      */
200     public void setAgendaId(String agendaId) {
201         this.agendaId = agendaId;
202     }
203 
204     /**
205      * @return the ruleId
206      */
207     public String getRuleId() {
208         return this.ruleId;
209     }
210 
211     /**
212      * @param ruleId the ruleId to set
213      */
214     public void setRuleId(String ruleId) {
215         this.ruleId = ruleId;
216     }
217 
218     /**
219      * @return the subAgendaId
220      */
221     public String getSubAgendaId() {
222         return this.subAgendaId;
223     }
224 
225     /**
226      * @param subAgendaId the subAgendaId to set
227      */
228     public void setSubAgendaId(String subAgendaId) {
229         this.subAgendaId = subAgendaId;
230     }
231 
232     /**
233      * @return the whenTrueId
234      */
235     public String getWhenTrueId() {
236         return this.whenTrueId;
237     }
238 
239     /**
240      * @param whenTrueId the whenTrueId to set
241      */
242     public void setWhenTrueId(String whenTrueId) {
243         this.whenTrueId = whenTrueId;
244     }
245 
246     /**
247      * @return the whenFalseId
248      */
249     public String getWhenFalseId() {
250         return this.whenFalseId;
251     }
252 
253     /**
254      * @param whenFalseId the whenFalseId to set
255      */
256     public void setWhenFalseId(String whenFalseId) {
257         this.whenFalseId = whenFalseId;
258     }
259 
260     /**
261      * @return the alwaysId
262      */
263     public String getAlwaysId() {
264         return this.alwaysId;
265     }
266 
267     /**
268      * @param alwaysId the alwaysId to set
269      */
270     public void setAlwaysId(String alwaysId) {
271         this.alwaysId = alwaysId;
272     }
273 
274     public Long getVersionNumber() {
275         return versionNumber;
276     }
277 
278     public void setVersionNumber(Long versionNumber) {
279         this.versionNumber = versionNumber;
280     }
281 
282     /**
283      * @return the whenTrue
284      */
285     public AgendaItemBo getWhenTrue() {
286         return this.whenTrue;
287     }
288 
289     /**
290      * @param whenTrue the whenTrue to set
291      */
292     public void setWhenTrue(AgendaItemBo whenTrue) {
293         this.whenTrue = whenTrue;
294 
295         if (whenTrue != null) {
296             setWhenTrueId(whenTrue.getId());
297         } else {
298             setWhenTrueId(null);
299         }
300     }
301 
302     /**
303      * @return the whenFalse
304      */
305     public AgendaItemBo getWhenFalse() {
306         return this.whenFalse;
307     }
308 
309     /**
310      * @param whenFalse the whenFalse to set
311      */
312     public void setWhenFalse(AgendaItemBo whenFalse) {
313         this.whenFalse = whenFalse;
314 
315         if (whenFalse != null) {
316             setWhenFalseId(whenFalse.getId());
317         } else {
318             setWhenFalseId(null);
319         }
320     }
321 
322     /**
323      * @return the always
324      */
325     public AgendaItemBo getAlways() {
326         return this.always;
327     }
328 
329     /**
330      * @param always the always to set
331      */
332     public void setAlways(AgendaItemBo always) {
333         this.always = always;
334         if (always != null) {
335             setAlwaysId(always.getId());
336         } else {
337             setAlwaysId(null);
338         }
339     }
340 
341     /**
342      * @return the rule
343      */
344     public RuleBo getRule() {
345         return this.rule;
346     }
347 
348     @Override
349     public AgendaDefinitionContract getSubAgenda() {
350         return null; // no sub-agenda support at this time
351     }
352 
353     /**
354      * @param rule the rule to set
355      */
356     public void setRule(RuleBo rule) {
357         this.rule = rule;
358         if (rule != null) {
359             setRuleId(rule.getId());
360         } else {
361             setRuleId(null);
362         }
363     }
364 
365     /**
366      * Converts a mutable bo to it's immutable counterpart
367      * @param bo the mutable business object
368      * @return the immutable object
369      */
370     static AgendaItemDefinition to(AgendaItemBo bo) {
371         if (bo == null) {
372             return null;
373         }
374 
375         AgendaItemDefinition.Builder builder = AgendaItemDefinition.Builder.create(bo);
376 
377         return builder.build();
378     }
379 
380     /**
381      * Converts a immutable object to it's mutable bo counterpart
382      * @param im immutable object
383      * @return the mutable bo
384      */
385     static AgendaItemBo from(AgendaItemDefinition im) {
386         if (im == null) {
387             return null;
388         }
389 
390         AgendaItemBo bo = new AgendaItemBo();
391         bo.id = im.getId();
392         bo.agendaId = im.getAgendaId();
393         bo.ruleId = im.getRuleId();
394         bo.subAgendaId = im.getSubAgendaId();
395         bo.whenTrueId = im.getWhenTrueId();
396         bo.whenFalseId = im.getWhenFalseId();
397         bo.alwaysId = im.getAlwaysId();
398         bo.versionNumber = im.getVersionNumber();
399         bo.rule = RuleBo.from(im.getRule());
400         bo.whenTrue = AgendaItemBo.from(im.getWhenTrue());
401         bo.whenFalse = AgendaItemBo.from(im.getWhenFalse());
402         bo.always = AgendaItemBo.from(im.getAlways());
403 
404         return bo;
405     }
406 
407     /**
408      * Returns a copy of this AgendaItem
409      * @param copiedAgenda the new Agenda that the copied AgendiaItem will be associated with
410      * @param oldRuleIdToNew Map<String, RuleBo> mapping of old rule id to the new RuleBo
411      * @param dts DateTimeStamp to append to the copied AgendaItem name
412      * @return AgendaItemBo copy of this AgendaItem with new id and name
413      */
414     public AgendaItemBo copyAgendaItem(AgendaBo copiedAgenda, Map<String, RuleBo> oldRuleIdToNew, Map<String, AgendaItemBo> oldAgendaItemIdToNew, List<AgendaItemBo> copiedAgendaItems, final String dts) {
415         // Use deepCopy and update all the ids.  
416         AgendaItemBo copiedAgendaItem = (AgendaItemBo) SerializationUtils.deepCopy(this);
417         copiedAgendaItem.setId(agendaItemIdIncrementer.getNewId());
418         copiedAgendaItem.setAgendaId(copiedAgenda.getId());
419         oldAgendaItemIdToNew.put(this.getId(), copiedAgendaItem);
420 
421         // Don't create another copy of a rule that we have already copied.  
422         if (!oldRuleIdToNew.containsKey(this.getRuleId())) {
423             if (this.getRule() != null) {
424                 copiedAgendaItem.setRule(this.getRule().copyRule(COPY_OF_TEXT + this.getRule().getName() + " " + dts));
425                 oldRuleIdToNew.put(this.getRuleId(), copiedAgendaItem.getRule());
426             }
427         } else {
428             copiedAgendaItem.setRule(oldRuleIdToNew.get(this.getRuleId()));
429         }
430 
431         if (copiedAgendaItem.getWhenFalse() != null) {
432             if (!oldAgendaItemIdToNew.containsKey(this.getWhenFalseId())) {
433                 copiedAgendaItem.setWhenFalse(this.getWhenFalse().copyAgendaItem(copiedAgenda, oldRuleIdToNew, oldAgendaItemIdToNew, copiedAgendaItems, dts));
434                 oldAgendaItemIdToNew.put(this.getWhenFalseId(), copiedAgendaItem.getWhenFalse());
435                 copiedAgendaItems.add(copiedAgendaItem.getWhenFalse());
436             } else {
437                 copiedAgendaItem.setWhenFalse(oldAgendaItemIdToNew.get(this.getWhenFalseId()));
438             }
439         }
440 
441         if (copiedAgendaItem.getWhenTrue() != null) {
442             if (!oldAgendaItemIdToNew.containsKey(this.getWhenTrueId())) {
443                 copiedAgendaItem.setWhenTrue(this.getWhenTrue().copyAgendaItem(copiedAgenda, oldRuleIdToNew, oldAgendaItemIdToNew, copiedAgendaItems, dts));
444                 oldAgendaItemIdToNew.put(this.getWhenTrueId(), copiedAgendaItem.getWhenTrue());
445                 copiedAgendaItems.add(copiedAgendaItem.getWhenTrue());
446             } else {
447                 copiedAgendaItem.setWhenTrue(oldAgendaItemIdToNew.get(this.getWhenTrueId()));
448             }
449         }
450 
451         if (copiedAgendaItem.getAlways() != null) {
452             if (!oldAgendaItemIdToNew.containsKey(this.getAlwaysId())) {
453                 copiedAgendaItem.setAlways(this.getAlways().copyAgendaItem(copiedAgenda, oldRuleIdToNew, oldAgendaItemIdToNew, copiedAgendaItems, dts));
454                 oldAgendaItemIdToNew.put(this.getAlwaysId(), copiedAgendaItem.getAlways());
455                 copiedAgendaItems.add(copiedAgendaItem.getAlways());
456             } else {
457                 copiedAgendaItem.setAlways(oldAgendaItemIdToNew.get(this.getAlwaysId()));
458             }
459         }
460         return copiedAgendaItem;
461     }
462 }