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}