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.lang.StringUtils;
19  import org.kuali.rice.core.api.util.io.SerializationUtils;
20  import org.kuali.rice.krad.data.jpa.converters.BooleanYNConverter;
21  import org.kuali.rice.krad.data.jpa.PortableSequenceGenerator;
22  import org.kuali.rice.krms.api.repository.agenda.AgendaDefinition;
23  import org.kuali.rice.krms.api.repository.context.ContextDefinition;
24  import org.kuali.rice.krms.api.repository.context.ContextDefinitionContract;
25  
26  import javax.persistence.CascadeType;
27  import javax.persistence.Column;
28  import javax.persistence.Convert;
29  import javax.persistence.Entity;
30  import javax.persistence.FetchType;
31  import javax.persistence.GeneratedValue;
32  import javax.persistence.Id;
33  import javax.persistence.JoinColumn;
34  import javax.persistence.OneToMany;
35  import javax.persistence.Table;
36  import javax.persistence.Version;
37  import java.io.IOException;
38  import java.io.ObjectOutputStream;
39  import java.io.Serializable;
40  import java.util.ArrayList;
41  import java.util.HashMap;
42  import java.util.List;
43  import java.util.Map;
44  
45  @Entity
46  @Table(name = "KRMS_CNTXT_T")
47  public class ContextBo implements ContextDefinitionContract, Serializable {
48  
49      private static final long serialVersionUID = 1L;
50  
51      public static final String CONTEXT_SEQ_NAME = "KRMS_CNTXT_S";
52  
53      @PortableSequenceGenerator(name = CONTEXT_SEQ_NAME)
54      @GeneratedValue(generator = CONTEXT_SEQ_NAME)
55      @Id
56      @Column(name = "CNTXT_ID")
57      private String id;
58  
59      @Column(name = "NM")
60      private String name;
61  
62      @Column(name = "NMSPC_CD")
63      private String namespace;
64  
65      @Column(name = "TYP_ID")
66      private String typeId;
67  
68      @Column(name = "DESC_TXT")
69      private String description;
70  
71      @Column(name = "ACTV")
72      @Convert(converter = BooleanYNConverter.class)
73      private boolean active = true;
74  
75      @OneToMany(mappedBy = "context")
76      @JoinColumn(name = "CNTXT_ID", referencedColumnName = "CNTXT_ID", insertable = false, updatable = false)
77      private List<AgendaBo> agendas = new ArrayList<AgendaBo>();
78  
79      @OneToMany(
80              targetEntity = ContextAttributeBo.class, orphanRemoval = true, mappedBy = "context",
81              cascade = { CascadeType.REFRESH, CascadeType.REMOVE, CascadeType.PERSIST },
82              fetch = FetchType.LAZY
83      )
84      @JoinColumn(name = "CNTXT_ID", referencedColumnName = "CNTXT_ID", insertable = true, updatable = true)
85      private List<ContextAttributeBo> attributeBos = new ArrayList<ContextAttributeBo>();
86  
87      @Column(name = "VER_NBR")
88      @Version
89      private Long versionNumber;
90  
91      @Override
92      public List<AgendaBo> getAgendas() {
93          return agendas;
94      }
95  
96      @Override
97      public Map<String, String> getAttributes() {
98          Map<String, String> attributes = new HashMap<String, String>();
99  
100         if (attributeBos != null) for (ContextAttributeBo attr : attributeBos) {
101             ((HashMap<String, String>) attributes).put(attr.getAttributeDefinition().getName(), attr.getValue());
102         }
103 
104         return attributes;
105     }
106 
107     public ContextBo copyContext(String additionalNameText) {
108         ContextBo copy = (ContextBo) SerializationUtils.deepCopy(this);
109 
110         //
111         // set all IDs to null
112         //
113 
114         copy.setId(null);
115 
116         // copying a context does not copy the associated agendas
117         copy.setAgendas(null);
118         for (ContextAttributeBo attributeBo : copy.getAttributeBos()) {
119             attributeBo.setId(null);
120         }
121 
122         if (!StringUtils.isEmpty(additionalNameText)) {
123             copy.setName(copy.getName() + additionalNameText);
124         }
125 
126         return copy;
127     }
128 
129     /**
130      * Converts a mutable bo to it's immutable counterpart
131      *
132      * @param bo the mutable business object
133      * @return the immutable object
134      */
135     public static ContextDefinition to(ContextBo bo) {
136         if (bo == null) {
137             return null;
138         }
139 
140         return ContextDefinition.Builder.create(bo).build();
141     }
142 
143     /**
144      * Converts a immutable object to it's mutable bo counterpart
145      *
146      * @param im immutable object
147      * @return the mutable bo
148      */
149     public static ContextBo from(ContextDefinition im) {
150         if (im == null) {
151             return null;
152         }
153 
154         ContextBo bo = new ContextBo();
155         bo.id = im.getId();
156         bo.namespace = im.getNamespace();
157         bo.name = im.getName();
158         bo.typeId = im.getTypeId();
159         bo.description = im.getDescription();
160         bo.active = im.isActive();
161         bo.agendas = new ArrayList<AgendaBo>();
162         for (AgendaDefinition agenda : im.getAgendas()) {
163             bo.agendas.add(KrmsRepositoryServiceLocator.getAgendaBoService().from(agenda));
164         }
165 
166         // build the list of agenda attribute BOs
167         List<ContextAttributeBo> attrs = new ArrayList<ContextAttributeBo>();
168 
169         // for each converted pair, build an AgendaAttributeBo and add it to the list
170         ContextAttributeBo attributeBo;
171         for (Map.Entry<String, String> entry : im.getAttributes().entrySet()) {
172             KrmsAttributeDefinitionBo attrDefBo =
173                     KrmsRepositoryServiceLocator.getKrmsAttributeDefinitionService().getKrmsAttributeBo(entry.getKey(), im.getNamespace());
174             attributeBo = new ContextAttributeBo();
175             attributeBo.setContext(bo);
176             attributeBo.setValue(entry.getValue());
177             attributeBo.setAttributeDefinition(attrDefBo);
178             attrs.add(attributeBo);
179         }
180 
181         bo.setAttributeBos(attrs);
182         bo.versionNumber = im.getVersionNumber();
183 
184         return bo;
185     }
186 
187      /*
188     This is being done because there is a  major issue with lazy relationships, in ensuring that the relationship is
189     still available after the object has been detached, or serialized. For most JPA providers, after serialization
190     any lazy relationship that was not instantiated will be broken, and either throw an error when accessed,
191     or return null.
192      */
193 
194     private void writeObject(ObjectOutputStream stream) throws IOException, ClassNotFoundException {
195         agendas.size();
196         attributeBos.size();
197         stream.defaultWriteObject();
198     }
199 
200     public String getId() {
201         return id;
202     }
203 
204     public void setId(String id) {
205         this.id = id;
206     }
207 
208     public String getName() {
209         return name;
210     }
211 
212     public void setName(String name) {
213         this.name = name;
214     }
215 
216     public String getNamespace() {
217         return namespace;
218     }
219 
220     public void setNamespace(String namespace) {
221         this.namespace = namespace;
222     }
223 
224     public String getTypeId() {
225         return typeId;
226     }
227 
228     public void setTypeId(String typeId) {
229         this.typeId = typeId;
230     }
231 
232     public String getDescription() {
233         return description;
234     }
235 
236     public void setDescription(String description) {
237         this.description = description;
238     }
239 
240     public boolean getActive() {
241         return active;
242     }
243 
244     public boolean isActive() {
245         return active;
246     }
247 
248     public void setActive(boolean active) {
249         this.active = active;
250     }
251 
252     public void setAgendas(List<AgendaBo> agendas) {
253         this.agendas = agendas;
254     }
255 
256     public List<ContextAttributeBo> getAttributeBos() {
257         return attributeBos;
258     }
259 
260     public void setAttributeBos(List<ContextAttributeBo> attributeBos) {
261         this.attributeBos = attributeBos;
262     }
263 
264     public Long getVersionNumber() {
265         return versionNumber;
266     }
267 
268     public void setVersionNumber(Long versionNumber) {
269         this.versionNumber = versionNumber;
270     }
271 }