001    /**
002     * Copyright 2005-2014 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     */
016    package org.kuali.rice.kim.impl.responsibility;
017    
018    import java.io.IOException;
019    import java.io.ObjectOutputStream;
020    import java.util.Iterator;
021    import java.util.List;
022    import java.util.Map;
023    
024    import javax.persistence.CascadeType;
025    import javax.persistence.Column;
026    import javax.persistence.Convert;
027    import javax.persistence.Entity;
028    import javax.persistence.GeneratedValue;
029    import javax.persistence.Id;
030    import javax.persistence.Inheritance;
031    import javax.persistence.InheritanceType;
032    import javax.persistence.JoinColumn;
033    import javax.persistence.ManyToOne;
034    import javax.persistence.OneToMany;
035    import javax.persistence.Table;
036    import javax.persistence.Transient;
037    
038    import org.kuali.rice.kim.api.KimConstants;
039    import org.kuali.rice.kim.api.responsibility.Responsibility;
040    import org.kuali.rice.kim.api.responsibility.ResponsibilityContract;
041    import org.kuali.rice.kim.api.services.KimApiServiceLocator;
042    import org.kuali.rice.kim.api.type.KimType;
043    import org.kuali.rice.kim.api.type.KimTypeAttribute;
044    import org.kuali.rice.kim.api.type.KimTypeInfoService;
045    import org.kuali.rice.kim.impl.common.attribute.KimAttributeDataBo;
046    import org.kuali.rice.kim.impl.role.RoleResponsibilityBo;
047    import org.kuali.rice.krad.bo.DataObjectBase;
048    import org.kuali.rice.krad.data.jpa.converters.BooleanYNConverter;
049    import org.kuali.rice.krad.data.jpa.PortableSequenceGenerator;
050    import org.kuali.rice.krad.service.DataDictionaryService;
051    import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
052    import org.springframework.util.AutoPopulatingList;
053    
054    @Entity
055    @Table(name = "KRIM_RSP_T")
056    @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
057    public class ResponsibilityBo extends DataObjectBase implements ResponsibilityContract {
058    
059        private static final long serialVersionUID = 1L;
060    
061        @PortableSequenceGenerator(name = "KRIM_RSP_ID_S")
062        @GeneratedValue(generator = "KRIM_RSP_ID_S")
063        @Id
064        @Column(name = "RSP_ID")
065        String id;
066    
067        @Column(name = "NMSPC_CD")
068        String namespaceCode;
069    
070        @Column(name = "NM")
071        String name;
072    
073        @Column(name = "DESC_TXT")
074        String description;
075    
076        @Column(name = "RSP_TMPL_ID")
077        String templateId;
078    
079        @Column(name = "ACTV_IND")
080        @Convert(converter = BooleanYNConverter.class)
081        boolean active;
082    
083        @ManyToOne(targetEntity = ResponsibilityTemplateBo.class, cascade = { CascadeType.REFRESH })
084        @JoinColumn(name = "RSP_TMPL_ID", referencedColumnName = "RSP_TMPL_ID", insertable = false, updatable = false)
085        ResponsibilityTemplateBo template = new ResponsibilityTemplateBo();
086    
087        @OneToMany(targetEntity = ResponsibilityAttributeBo.class, orphanRemoval = true, cascade = { CascadeType.ALL })
088        @JoinColumn(name = "RSP_ID", referencedColumnName = "RSP_ID")
089        List<ResponsibilityAttributeBo> attributeDetails = new AutoPopulatingList<ResponsibilityAttributeBo>(ResponsibilityAttributeBo.class);
090    
091        @OneToMany(mappedBy = "kimResponsibility")
092        @JoinColumn(name = "RSP_ID", referencedColumnName = "RSP_ID", insertable = false, updatable = false)
093        List<RoleResponsibilityBo> roleResponsibilities = new AutoPopulatingList<RoleResponsibilityBo>(RoleResponsibilityBo.class);
094    
095        @Transient
096        Map<String, String> attributes;
097    
098        @Override
099        public Map<String, String> getAttributes() {
100            return attributeDetails != null ? KimAttributeDataBo.toAttributes(attributeDetails) : attributes;
101        }
102    
103        /**
104         * Converts a mutable bo to its immutable counterpart
105         *
106         * @param bo the mutable business object
107         * @return the immutable object
108         */
109        public static Responsibility to(ResponsibilityContract bo) {
110            if (bo == null) {
111                return null;
112            }
113            return Responsibility.Builder.create(bo).build();
114        }
115    
116        /**
117         * Converts a immutable object to its mutable counterpart
118         *
119         * @param im immutable object
120         * @return the mutable bo
121         */
122        public static ResponsibilityBo from(Responsibility im) {
123            if (im == null) {
124                return null;
125            }
126            ResponsibilityBo bo = new ResponsibilityBo();
127            bo.id = im.getId();
128            bo.namespaceCode = im.getNamespaceCode();
129            bo.name = im.getName();
130            bo.description = im.getDescription();
131            bo.active = im.isActive();
132            bo.templateId = im.getTemplate() != null ? im.getTemplate().getId() : null;
133            bo.template = ResponsibilityTemplateBo.from(im.getTemplate());
134            bo.attributes = im.getAttributes();
135            bo.setVersionNumber(im.getVersionNumber());
136            bo.setObjectId(im.getObjectId());
137            return bo;
138        }
139    
140        @Override
141        public ResponsibilityTemplateBo getTemplate() {
142            return template;
143        }
144    
145        public String getDetailObjectsValues() {
146            StringBuffer detailObjectsToDisplayBuffer = new StringBuffer();
147            Iterator<ResponsibilityAttributeBo> respIter = attributeDetails.iterator();
148            while (respIter.hasNext()) {
149                ResponsibilityAttributeBo respAttributeData = respIter.next();
150                detailObjectsToDisplayBuffer.append(respAttributeData.getAttributeValue());
151                if (respIter.hasNext()) {
152                    detailObjectsToDisplayBuffer.append(KimConstants.KimUIConstants.COMMA_SEPARATOR);
153                }
154            }
155            return detailObjectsToDisplayBuffer.toString();
156        }
157    
158        public String getDetailObjectsToDisplay() {
159            final KimType kimType = getTypeInfoService().getKimType(getTemplate().getKimTypeId());
160            StringBuffer detailObjects = new StringBuffer();
161            Iterator<ResponsibilityAttributeBo> respIter = attributeDetails.iterator();
162            while (respIter.hasNext()) {
163                ResponsibilityAttributeBo bo = respIter.next();
164                detailObjects.append(getKimAttributeLabelFromDD(kimType.getAttributeDefinitionById(bo.getKimAttributeId()))).append(":").append(bo.getAttributeValue());
165                if (respIter.hasNext()) {
166                    detailObjects.append(KimConstants.KimUIConstants.COMMA_SEPARATOR);
167                }
168            }
169            return detailObjects.toString();
170        }
171    
172        private String getKimAttributeLabelFromDD(KimTypeAttribute attribute) {
173            return getDataDictionaryService().getAttributeLabel(attribute.getKimAttribute().getComponentName(), attribute.getKimAttribute().getAttributeName());
174        }
175    
176        private DataDictionaryService getDataDictionaryService() {
177            return KRADServiceLocatorWeb.getDataDictionaryService();
178        }
179    
180        private KimTypeInfoService getTypeInfoService() {
181            return KimApiServiceLocator.getKimTypeInfoService();
182        }
183    
184        /*
185        This is being done because there is a  major issue with lazy relationships, in ensuring that the relationship is
186        still available after the object has been detached, or serialized. For most JPA providers, after serialization
187        any lazy relationship that was not instantiated will be broken, and either throw an error when accessed,
188        or return null.
189         */
190    
191        private void writeObject(ObjectOutputStream stream) throws IOException, ClassNotFoundException {
192            attributeDetails.size();
193            roleResponsibilities.size();
194            stream.defaultWriteObject();
195        }
196    
197        @Override
198        public String getId() {
199            return id;
200        }
201    
202        public void setId(String id) {
203            this.id = id;
204        }
205    
206        @Override
207        public String getNamespaceCode() {
208            return namespaceCode;
209        }
210    
211        public void setNamespaceCode(String namespaceCode) {
212            this.namespaceCode = namespaceCode;
213        }
214    
215        @Override
216        public String getName() {
217            return name;
218        }
219    
220        public void setName(String name) {
221            this.name = name;
222        }
223    
224        @Override
225        public String getDescription() {
226            return description;
227        }
228    
229        public void setDescription(String description) {
230            this.description = description;
231        }
232    
233        public String getTemplateId() {
234            return templateId;
235        }
236    
237        public void setTemplateId(String templateId) {
238            this.templateId = templateId;
239        }
240    
241        public boolean getActive() {
242            return active;
243        }
244    
245        @Override
246        public boolean isActive() {
247            return active;
248        }
249    
250        public void setActive(boolean active) {
251            this.active = active;
252        }
253    
254        public void setTemplate(ResponsibilityTemplateBo template) {
255            this.template = template;
256        }
257    
258        public List<ResponsibilityAttributeBo> getAttributeDetails() {
259            return attributeDetails;
260        }
261    
262        public void setAttributeDetails(List<ResponsibilityAttributeBo> attributeDetails) {
263            this.attributeDetails = attributeDetails;
264        }
265    
266        public List<RoleResponsibilityBo> getRoleResponsibilities() {
267            return roleResponsibilities;
268        }
269    
270        public void setRoleResponsibilities(List<RoleResponsibilityBo> roleResponsibilities) {
271            this.roleResponsibilities = roleResponsibilities;
272        }
273    
274        public void setAttributes(Map<String, String> attributes) {
275            this.attributes = attributes;
276        }
277    }