001/** 002 * Copyright 2005-2017 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 java.io.Serializable; 019import java.util.ArrayList; 020import java.util.HashMap; 021import java.util.HashSet; 022import java.util.List; 023import java.util.Map; 024import java.util.Set; 025 026import javax.persistence.CascadeType; 027import javax.persistence.Column; 028import javax.persistence.Convert; 029import javax.persistence.Entity; 030import javax.persistence.GeneratedValue; 031import javax.persistence.Id; 032import javax.persistence.JoinColumn; 033import javax.persistence.ManyToOne; 034import javax.persistence.OneToMany; 035import javax.persistence.Table; 036import javax.persistence.Version; 037 038import org.apache.commons.lang.StringUtils; 039import org.kuali.rice.krad.data.CopyOption; 040import org.kuali.rice.krad.data.KradDataServiceLocator; 041import org.kuali.rice.krad.data.jpa.PortableSequenceGenerator; 042import org.kuali.rice.krad.data.jpa.converters.BooleanYNConverter; 043import org.kuali.rice.krms.api.repository.agenda.AgendaDefinition; 044import org.kuali.rice.krms.api.repository.agenda.AgendaDefinitionContract; 045import org.kuali.rice.krms.api.repository.type.KrmsAttributeDefinition; 046 047@Entity 048@Table(name = "KRMS_AGENDA_T") 049public class AgendaBo implements AgendaDefinitionContract, Serializable { 050 051 private static final long serialVersionUID = 1L; 052 053 public static final String AGENDA_SEQ_NAME = "KRMS_AGENDA_S"; 054 static final RepositoryBoIncrementer agendaIdIncrementer = new RepositoryBoIncrementer(AGENDA_SEQ_NAME); 055 056 @PortableSequenceGenerator(name = AGENDA_SEQ_NAME) 057 @GeneratedValue(generator = AGENDA_SEQ_NAME) 058 @Id 059 @Column(name = "AGENDA_ID") 060 private String id; 061 062 @Column(name = "NM") 063 private String name; 064 065 @Column(name = "TYP_ID") 066 private String typeId; 067 068 @Column(name = "CNTXT_ID") 069 private String contextId; 070 071 @Column(name = "ACTV") 072 @Convert(converter = BooleanYNConverter.class) 073 private boolean active = true; 074 075 @Column(name = "INIT_AGENDA_ITM_ID", insertable = false, updatable = false) 076 private String firstItemId; 077 078 @ManyToOne(targetEntity = AgendaItemBo.class, cascade = { CascadeType.REFRESH, CascadeType.REMOVE, CascadeType.MERGE, CascadeType.PERSIST }) 079 @JoinColumn(name = "INIT_AGENDA_ITM_ID") 080 private AgendaItemBo firstItem; 081 082 @Column(name = "VER_NBR") 083 @Version 084 private Long versionNumber; 085 086 @OneToMany(orphanRemoval = true, mappedBy = "agenda", targetEntity = AgendaAttributeBo.class, 087 cascade = { CascadeType.REFRESH, CascadeType.MERGE, CascadeType.REMOVE, CascadeType.PERSIST }) 088 @JoinColumn(name = "AGENDA_ID", referencedColumnName = "AGENDA_ID", insertable = true, updatable = true) 089 private Set<AgendaAttributeBo> attributeBos; 090 091 @OneToMany(orphanRemoval = true, targetEntity = AgendaItemBo.class, cascade = { CascadeType.REFRESH}) 092 @JoinColumn(name = "AGENDA_ID", referencedColumnName = "AGENDA_ID", insertable = false, updatable = false) 093 private List<AgendaItemBo> items; 094 095 @ManyToOne(targetEntity = ContextBo.class, cascade = { CascadeType.REFRESH }) 096 @JoinColumn(name = "CNTXT_ID", referencedColumnName = "CNTXT_ID", insertable = false, updatable = false) 097 private ContextBo context; 098 099 public AgendaBo() { 100 active = true; 101 items = new ArrayList<AgendaItemBo>(); 102 } 103 104 public AgendaBo getAgenda() { 105 return this; 106 } 107 108 @Override 109 public Map<String, String> getAttributes() { 110 HashMap<String, String> attributes = new HashMap<String, String>(); 111 112 if (attributeBos != null) { 113 for (AgendaAttributeBo attr : attributeBos) { 114 attributes.put(attr.getAttributeDefinition().getName(), attr.getValue()); 115 } 116 } 117 118 return attributes; 119 } 120 121 public void setAttributes(Map<String, String> attributes) { 122 this.attributeBos = new HashSet<AgendaAttributeBo>(); 123 124 if (!StringUtils.isBlank(this.typeId)) { 125 List<KrmsAttributeDefinition> attributeDefinitions = KrmsRepositoryServiceLocator.getKrmsAttributeDefinitionService().findAttributeDefinitionsByType(this.getTypeId()); 126 Map<String, KrmsAttributeDefinition> attributeDefinitionsByName = new HashMap<String, KrmsAttributeDefinition>(); 127 128 if (attributeDefinitions != null) { 129 for (KrmsAttributeDefinition attributeDefinition : attributeDefinitions) { 130 attributeDefinitionsByName.put(attributeDefinition.getName(), attributeDefinition); 131 } 132 } 133 134 for (Map.Entry<String, String> attr : attributes.entrySet()) { 135 KrmsAttributeDefinition attributeDefinition = attributeDefinitionsByName.get(attr.getKey()); 136 AgendaAttributeBo attributeBo = new AgendaAttributeBo(); 137 attributeBo.setAgenda(this); 138 attributeBo.setValue(attr.getValue()); 139 attributeBo.setAttributeDefinition(KrmsAttributeDefinitionBo.from(attributeDefinition)); 140 attributeBos.add(attributeBo); 141 } 142 } 143 } 144 145 /** 146 * Returns of copy of this agenda, with the given newAgendaName and new ids. 147 * 148 * @param newAgendaName name of the newly copied AgendaBo 149 * @param dateTimeStamp to append to the names of objects 150 * @return AgendaBo copy of this Agenda with new ids and name 151 */ 152 public AgendaBo copyAgenda(String newAgendaName, String dateTimeStamp) { 153 List<AgendaItemBo> agendaItems = this.getItems(); 154 AgendaBo copiedAgenda = KradDataServiceLocator.getDataObjectService().copyInstance(this, CopyOption.RESET_PK_FIELDS, CopyOption.RESET_OBJECT_ID ); 155 copiedAgenda.setName(newAgendaName); 156 157 // Using a copiedAgenda we don't mess with the existing agenda at all. 158 copiedAgenda.setId(agendaIdIncrementer.getNewId()); 159 160 String initAgendaItemId = this.getFirstItemId(); 161 List<AgendaItemBo> copiedAgendaItems = new ArrayList<AgendaItemBo>(); 162 Map<String, RuleBo> oldRuleIdToNew = new HashMap<String, RuleBo>(); 163 Map<String, AgendaItemBo> oldAgendaItemIdToNew = new HashMap<String, AgendaItemBo>(); 164 165 for (AgendaItemBo agendaItem : agendaItems) { 166 if (!oldAgendaItemIdToNew.containsKey(agendaItem.getId())) { 167 AgendaItemBo copiedAgendaItem = 168 agendaItem.copyAgendaItem(copiedAgenda, oldRuleIdToNew, oldAgendaItemIdToNew, copiedAgendaItems, dateTimeStamp); 169 170 if (initAgendaItemId != null && initAgendaItemId.equals(agendaItem.getId())) { 171 copiedAgenda.setFirstItemId(copiedAgendaItem.getId()); 172 copiedAgenda.setFirstItem(copiedAgendaItem); 173 } 174 175 copiedAgendaItems.add(copiedAgendaItem); 176 oldAgendaItemIdToNew.put(agendaItem.getId(), copiedAgendaItem); 177 } 178 } 179 180 copiedAgenda.setItems(copiedAgendaItems); 181 182 return copiedAgenda; 183 } 184 185 /** 186 * Converts a mutable bo to it's immutable counterpart 187 * 188 * @param bo the mutable business object 189 * @return the immutable object AgendaDefinition 190 */ 191 public static AgendaDefinition to(AgendaBo bo) { 192 if (bo == null) { 193 return null; 194 } 195 196 return AgendaDefinition.Builder.create(bo).build(); 197 } 198 199 @Override 200 public String getId() { 201 return id; 202 } 203 204 public void setId(String id) { 205 this.id = id; 206 } 207 208 @Override 209 public String getName() { 210 return name; 211 } 212 213 public void setName(String name) { 214 this.name = name; 215 } 216 217 @Override 218 public String getTypeId() { 219 return typeId; 220 } 221 222 public void setTypeId(String typeId) { 223 this.typeId = typeId; 224 } 225 226 @Override 227 public String getContextId() { 228 return contextId; 229 } 230 231 public void setContextId(String contextId) { 232 this.contextId = contextId; 233 } 234 235 public boolean getActive() { 236 return active; 237 } 238 239 @Override 240 public boolean isActive() { 241 return active; 242 } 243 244 public void setActive(boolean active) { 245 this.active = active; 246 } 247 248 @Override 249 public String getFirstItemId() { 250 return firstItemId; 251 } 252 253 public void setFirstItemId(String firstItemId) { 254 this.firstItemId = firstItemId; 255 } 256 257 public AgendaItemBo getFirstItem() { 258 return firstItem; 259 } 260 261 public void setFirstItem(AgendaItemBo firstItem) { 262 this.firstItem = firstItem; 263 264 if (firstItem != null) { 265 firstItemId = firstItem.getId(); 266 } 267 } 268 269 public Set<AgendaAttributeBo> getAttributeBos() { 270 return attributeBos; 271 } 272 273 public void setAttributeBos(Set<AgendaAttributeBo> attributeBos) { 274 this.attributeBos = attributeBos; 275 } 276 277 public List<AgendaItemBo> getItems() { 278 return items; 279 } 280 281 public void setItems(List<AgendaItemBo> items) { 282 this.items = items; 283 } 284 285 public ContextBo getContext() { 286 return context; 287 } 288 289 public void setContext(ContextBo context) { 290 this.context = context; 291 } 292 293 @Override 294 public Long getVersionNumber() { 295 return versionNumber; 296 } 297 298 public void setVersionNumber(Long versionNumber) { 299 this.versionNumber = versionNumber; 300 } 301}