001/** 002 * Copyright 2005-2016 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.kuali.rice.krms.impl.repository; 017 018import org.apache.commons.collections.CollectionUtils; 019import org.apache.commons.lang.StringUtils; 020import org.kuali.rice.krad.bo.PersistableBusinessObjectBase; 021import org.kuali.rice.krad.service.KRADServiceLocator; 022import org.kuali.rice.krad.service.SequenceAccessorService; 023import org.kuali.rice.krad.util.ObjectUtils; 024import org.kuali.rice.krms.api.repository.agenda.AgendaItemDefinition; 025import org.kuali.rice.krms.api.repository.type.KrmsTypeDefinition; 026 027import java.util.ArrayList; 028import java.util.List; 029import java.util.Map; 030 031/** 032 * Agenda Item business object 033 * 034 * @author Kuali Rice Team (rice.collab@kuali.org) 035 * 036 */ 037public class AgendaItemBo extends PersistableBusinessObjectBase { 038 039 public static final String COPY_OF_TEXT = "Copy of "; 040 private static final String KRMS_AGENDA_ITM_S = "KRMS_AGENDA_ITM_S"; 041 042 private String id; 043 private String agendaId; 044 private String ruleId; 045 private String subAgendaId; 046 private String whenTrueId; 047 private String whenFalseId; 048 private String alwaysId; 049 050 private RuleBo rule; 051 052 private AgendaItemBo whenTrue; 053 private AgendaItemBo whenFalse; 054 private AgendaItemBo always; 055 056 private static SequenceAccessorService sequenceAccessorService; 057 058 public String getUl(AgendaItemBo firstItem) { 059 return ("<ul>" + getUlHelper(firstItem) + "</ul>"); 060 } 061 062 public String getUlHelper(AgendaItemBo item) { 063 StringBuilder sb = new StringBuilder(); 064 sb.append("<li>" + ruleId + "</li>"); 065 if (whenTrue != null) { 066 sb.append("<ul><li>when true</li><ul>"); 067 sb.append(getUlHelper(whenTrue)); 068 sb.append("</ul></ul>"); 069 } 070 if (whenFalse != null) { 071 sb.append("<ul><li>when false</li><ul>"); 072 sb.append(getUlHelper(whenFalse)); 073 sb.append("</ul></ul>"); 074 } 075 if (always != null) { 076 sb.append(getUlHelper(always)); 077 } 078 return sb.toString(); 079 } 080 081 public String getRuleText() { 082 StringBuilder resultBuilder = new StringBuilder(); 083 if (getRule() != null) { 084 if (StringUtils.isBlank(getRule().getName())) { 085 resultBuilder.append("- unnamed rule -"); 086 } else { 087 resultBuilder.append(getRule().getName()); 088 } 089 if (!StringUtils.isBlank(getRule().getDescription())) { 090 resultBuilder.append(": "); 091 resultBuilder.append(getRule().getDescription()); 092 } 093 // add a description of the action configured on the rule, if there is one 094 if (!CollectionUtils.isEmpty(getRule().getActions())) { 095 resultBuilder.append(" ["); 096 ActionBo action = getRule().getActions().get(0); 097 098 KrmsTypeDefinition krmsTypeDefn = 099 KrmsRepositoryServiceLocator.getKrmsTypeRepositoryService().getTypeById(action.getTypeId()); 100 101 resultBuilder.append(krmsTypeDefn.getName()); 102 resultBuilder.append(": "); 103 resultBuilder.append(action.getName()); 104 105 if (getRule().getActions().size() > 1) { 106 resultBuilder.append(" ... "); 107 } 108 resultBuilder.append("]"); 109 } 110 } else { 111 throw new IllegalStateException(); 112 } 113 return resultBuilder.toString(); 114 } 115 116// def List<AgendaItemBo> alwaysList 117// def List<AgendaItemBo> whenTrueList 118// def List<AgendaItemBo> whenFalseList 119 120 public List<AgendaItemBo> getAlwaysList() { 121 List<AgendaItemBo> results = new ArrayList<AgendaItemBo>(); 122 123 AgendaItemBo currentNode = this; 124 while (currentNode.always != null) { 125 results.add(currentNode.always); 126 currentNode = currentNode.always; 127 } 128 129 return results; 130 } 131 132 /** 133 * @return the id 134 */ 135 public String getId() { 136 return this.id; 137 } 138 139 /** 140 * @param id the id to set 141 */ 142 public void setId(String id) { 143 this.id = id; 144 } 145 146 /** 147 * @return the agendaId 148 */ 149 public String getAgendaId() { 150 return this.agendaId; 151 } 152 153 /** 154 * @param agendaId the agendaId to set 155 */ 156 public void setAgendaId(String agendaId) { 157 this.agendaId = agendaId; 158 } 159 160 /** 161 * @return the ruleId 162 */ 163 public String getRuleId() { 164 return this.ruleId; 165 } 166 167 /** 168 * @param ruleId the ruleId to set 169 */ 170 public void setRuleId(String ruleId) { 171 this.ruleId = ruleId; 172 } 173 174 /** 175 * @return the subAgendaId 176 */ 177 public String getSubAgendaId() { 178 return this.subAgendaId; 179 } 180 181 /** 182 * @param subAgendaId the subAgendaId to set 183 */ 184 public void setSubAgendaId(String subAgendaId) { 185 this.subAgendaId = subAgendaId; 186 } 187 188 189 /** 190 * @return the whenTrueId 191 */ 192 public String getWhenTrueId() { 193 return this.whenTrueId; 194 } 195 196 /** 197 * @param whenTrueId the whenTrueId to set 198 */ 199 public void setWhenTrueId(String whenTrueId) { 200 this.whenTrueId = whenTrueId; 201 } 202 203 /** 204 * @return the whenFalseId 205 */ 206 public String getWhenFalseId() { 207 return this.whenFalseId; 208 } 209 210 /** 211 * @param whenFalseId the whenFalseId to set 212 */ 213 public void setWhenFalseId(String whenFalseId) { 214 this.whenFalseId = whenFalseId; 215 } 216 217 /** 218 * @return the alwaysId 219 */ 220 public String getAlwaysId() { 221 return this.alwaysId; 222 } 223 224 /** 225 * @param alwaysId the alwaysId to set 226 */ 227 public void setAlwaysId(String alwaysId) { 228 this.alwaysId = alwaysId; 229 } 230 231 /** 232 * @return the whenTrue 233 */ 234 public AgendaItemBo getWhenTrue() { 235 return this.whenTrue; 236 } 237 238 /** 239 * @param whenTrue the whenTrue to set 240 */ 241 public void setWhenTrue(AgendaItemBo whenTrue) { 242 this.whenTrue = whenTrue; 243 if (whenTrue != null) { 244 setWhenTrueId(whenTrue.getId()); 245 } else { 246 setWhenTrueId(null); 247 } 248 } 249 250 /** 251 * @return the whenFalse 252 */ 253 public AgendaItemBo getWhenFalse() { 254 return this.whenFalse; 255 } 256 257 /** 258 * @param whenFalse the whenFalse to set 259 */ 260 public void setWhenFalse(AgendaItemBo whenFalse) { 261 this.whenFalse = whenFalse; 262 if (whenFalse != null) { 263 setWhenFalseId(whenFalse.getId()); 264 } else { 265 setWhenFalseId(null); 266 } 267 } 268 269 /** 270 * @return the always 271 */ 272 public AgendaItemBo getAlways() { 273 return this.always; 274 } 275 276 /** 277 * @param always the always to set 278 */ 279 public void setAlways(AgendaItemBo always) { 280 this.always = always; 281 if (always != null) { 282 setAlwaysId(always.getId()); 283 } else { 284 setAlwaysId(null); 285 } 286 } 287 288 /** 289 * @return the rule 290 */ 291 public RuleBo getRule() { 292 return this.rule; 293 } 294 295 /** 296 * @param rule the rule to set 297 */ 298 public void setRule(RuleBo rule) { 299 this.rule = rule; 300 if (rule != null) { 301 setRuleId(rule.getId()); 302 } else { 303 setRuleId(null); 304 } 305 } 306 307 308 /** 309 * Converts a mutable bo to it's immutable counterpart 310 * @param bo the mutable business object 311 * @return the immutable object 312 */ 313 static AgendaItemDefinition to(AgendaItemBo bo) { 314 if (bo == null) { return null; } 315 AgendaItemDefinition.Builder builder = 316 AgendaItemDefinition.Builder.create(bo.getId(), bo.getAgendaId()); 317 builder.setRuleId(bo.getRuleId()); 318 builder.setSubAgendaId(bo.getSubAgendaId()); 319 builder.setWhenTrueId(bo.getWhenTrueId()); 320 builder.setWhenFalseId(bo.getWhenFalseId()); 321 builder.setAlwaysId(bo.getAlwaysId()); 322 323 return builder.build(); 324 } 325 326 /** 327 * Converts a immutable object to it's mutable bo counterpart 328 * @param im immutable object 329 * @return the mutable bo 330 */ 331 static AgendaItemBo from(AgendaItemDefinition im) { 332 if (im == null) { return null; } 333 334 AgendaItemBo bo = new AgendaItemBo(); 335 bo.id = im.getId(); 336 bo.agendaId = im.getAgendaId(); 337 bo.ruleId = im.getRuleId(); 338 bo.subAgendaId = im.getSubAgendaId(); 339 bo.whenTrueId = im.getWhenTrueId(); 340 bo.whenFalseId = im.getWhenFalseId(); 341 bo.alwaysId = im.getAlwaysId(); 342 343 return bo; 344 } 345 346 /** 347 * Returns a copy of this AgendaItem 348 * @param copiedAgenda the new Agenda that the copied AgendiaItem will be associated with 349 * @param oldRuleIdToNew Map<String, RuleBo> mapping of old rule id to the new RuleBo 350 * @param dts DateTimeStamp to append to the copied AgendaItem name 351 * @return AgendaItemBo copy of this AgendaItem with new id and name 352 */ 353 public AgendaItemBo copyAgendaItem(AgendaBo copiedAgenda, Map<String, RuleBo> oldRuleIdToNew, 354 Map<String, AgendaItemBo> oldAgendaItemIdToNew, List<AgendaItemBo> copiedAgendaItems, final String dts) { 355 // Use deepCopy and update all the ids. 356 AgendaItemBo copiedAgendaItem = (AgendaItemBo) ObjectUtils.deepCopy(this); 357 copiedAgendaItem.setId(getNewId()); 358 copiedAgendaItem.setAgendaId(copiedAgenda.getId()); 359 360 oldAgendaItemIdToNew.put(this.getId(), copiedAgendaItem); 361 362 // Don't create another copy of a rule that we have already copied. 363 if (!oldRuleIdToNew.containsKey(this.getRuleId())) { 364 if (this.getRule() != null) { 365 copiedAgendaItem.setRule(this.getRule().copyRule(COPY_OF_TEXT + this.getRule().getName() + " " + dts)); 366 oldRuleIdToNew.put(this.getRuleId(), copiedAgendaItem.getRule()); 367 } 368 } else { 369 copiedAgendaItem.setRule(oldRuleIdToNew.get(this.getRuleId())); 370 } 371 372 if (copiedAgendaItem.getWhenFalse() != null) { 373 if (!oldAgendaItemIdToNew.containsKey(this.getWhenFalseId())) { 374 copiedAgendaItem.setWhenFalse(this.getWhenFalse().copyAgendaItem(copiedAgenda, oldRuleIdToNew, oldAgendaItemIdToNew, copiedAgendaItems, dts)); 375 oldAgendaItemIdToNew.put(this.getWhenFalseId(), copiedAgendaItem.getWhenFalse()); 376 copiedAgendaItems.add(copiedAgendaItem.getWhenFalse()); 377 } else { 378 copiedAgendaItem.setWhenFalse(oldAgendaItemIdToNew.get(this.getWhenFalseId())); 379 } 380 } 381 382 if (copiedAgendaItem.getWhenTrue() != null) { 383 if (!oldAgendaItemIdToNew.containsKey(this.getWhenTrueId())) { 384 copiedAgendaItem.setWhenTrue(this.getWhenTrue().copyAgendaItem(copiedAgenda, oldRuleIdToNew, oldAgendaItemIdToNew, copiedAgendaItems, dts)); 385 oldAgendaItemIdToNew.put(this.getWhenTrueId(), copiedAgendaItem.getWhenTrue()); 386 copiedAgendaItems.add(copiedAgendaItem.getWhenTrue()); 387 } else { 388 copiedAgendaItem.setWhenTrue(oldAgendaItemIdToNew.get(this.getWhenTrueId())); 389 } 390 } 391 392 if (copiedAgendaItem.getAlways() != null) { 393 if (!oldAgendaItemIdToNew.containsKey(this.getAlwaysId())) { 394 copiedAgendaItem.setAlways(this.getAlways().copyAgendaItem(copiedAgenda, oldRuleIdToNew, oldAgendaItemIdToNew, copiedAgendaItems, dts)); 395 oldAgendaItemIdToNew.put(this.getAlwaysId(), copiedAgendaItem.getAlways()); 396 copiedAgendaItems.add(copiedAgendaItem.getAlways()); 397 } else { 398 copiedAgendaItem.setAlways(oldAgendaItemIdToNew.get(this.getAlwaysId())); 399 } 400 } 401 return copiedAgendaItem; 402 } 403 404 405 /** 406 * Set the SequenceAccessorService, useful for testing. 407 * @param sas SequenceAccessorService to use for getNewId() 408 */ 409 public static void setSequenceAccessorService(SequenceAccessorService sas) { 410 sequenceAccessorService = sas; 411 } 412 413 /** 414 * Returns the next available AgendaItem id. 415 * @return String the next available id 416 */ 417 private static String getNewId() { 418 if (sequenceAccessorService == null) { 419 // we don't assign to sequenceAccessorService to preserve existing behavior 420 return KRADServiceLocator.getSequenceAccessorService().getNextAvailableSequenceNumber(KRMS_AGENDA_ITM_S, AgendaItemBo.class) + ""; 421 } 422 Long id = sequenceAccessorService.getNextAvailableSequenceNumber(KRMS_AGENDA_ITM_S, AgendaItemBo.class); 423 return id.toString(); 424 } 425}