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