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 }