001/** 002 * Copyright 2005-2016 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.krad.bo; 017 018import org.apache.commons.lang.StringUtils; 019import org.apache.ojb.broker.PersistenceBroker; 020import org.apache.ojb.broker.PersistenceBrokerAware; 021import org.apache.ojb.broker.PersistenceBrokerException; 022import org.kuali.rice.core.api.mo.common.GloballyUnique; 023import org.kuali.rice.core.api.mo.common.Versioned; 024import org.kuali.rice.kns.service.KNSServiceLocator; 025import org.kuali.rice.krad.service.KRADServiceLocator; 026import org.kuali.rice.krad.service.LegacyAppFrameworkAdapterService; 027import org.kuali.rice.krad.util.LegacyDataFramework; 028 029import javax.persistence.Column; 030import javax.persistence.Embeddable; 031import javax.persistence.MappedSuperclass; 032import javax.persistence.PostLoad; 033import javax.persistence.PostPersist; 034import javax.persistence.PostRemove; 035import javax.persistence.PostUpdate; 036import javax.persistence.PrePersist; 037import javax.persistence.PreRemove; 038import javax.persistence.PreUpdate; 039import javax.persistence.Transient; 040import javax.persistence.Version; 041 042import java.util.ArrayList; 043import java.util.Collection; 044import java.util.List; 045import java.util.UUID; 046 047/** 048 * @author Kuali Rice Team (rice.collab@kuali.org) 049 * @deprecated use new KRAD Data framework {@link org.kuali.rice.krad.data.DataObjectService}. 050 * In this framework, data objects are not required to have a superclass and can 051 * be POJO's but they can optionally use {@link org.kuali.rice.krad.bo.DataObjectBase} 052 * to emulate previous functionality. 053 */ 054@Deprecated 055@MappedSuperclass 056public abstract class PersistableBusinessObjectBase extends BusinessObjectBase implements PersistableBusinessObject, PersistenceBrokerAware, Versioned, GloballyUnique { 057 058 /** 059 * EclipseLink static weaving does not weave MappedSuperclass unless an Entity or Embedded is 060 * weaved which uses it, hence this class. 061 */ 062 @Embeddable 063 private static final class WeaveMe extends PersistableBusinessObjectBase {} 064 065 private static final long serialVersionUID = 1451642350593233282L; 066 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PersistableBusinessObjectBase.class); 067 068 @Version 069 @Column(name = "VER_NBR", length = 8) 070 protected Long versionNumber; 071 072 @Column(name = "OBJ_ID", length = 36, unique = true) 073 protected String objectId; 074 075 @Transient protected boolean newCollectionRecord; 076 @Transient protected PersistableBusinessObjectExtension extension; 077 078 private static transient LegacyAppFrameworkAdapterService legacyDataAdapter; 079 080 @Override 081 public Long getVersionNumber() { 082 return versionNumber; 083 } 084 085 @Override 086 public void setVersionNumber(Long versionNumber) { 087 this.versionNumber = versionNumber; 088 } 089 090 @Override 091 public String getObjectId() { 092 return objectId; 093 } 094 095 @Override 096 public void setObjectId(String objectId) { 097 this.objectId = objectId; 098 } 099 100 /** 101 * Gets the newCollectionRecord attribute. 102 * 103 * @return Returns the newCollectionRecord. 104 */ 105 @Override 106 public boolean isNewCollectionRecord() { 107 return newCollectionRecord; 108 } 109 110 /** 111 * Sets the newCollectionRecord attribute value. 112 * 113 * @param isNewCollectionRecord The newCollectionRecord to set. 114 */ 115 @Override 116 public void setNewCollectionRecord(boolean isNewCollectionRecord) { 117 this.newCollectionRecord = isNewCollectionRecord; 118 } 119 120 /** 121 * Implementation of the OJB afterDelete hook which delegates to {@link #postRemove()}. This method is final 122 * because it is recommended that sub-classes override and implement postRemove if they need to take 123 * advantage of this persistence hook. 124 * 125 * @see org.apache.ojb.broker.PersistenceBrokerAware#afterDelete(org.apache.ojb.broker.PersistenceBroker) 126 */ 127 @Override 128 @LegacyDataFramework 129 public final void afterDelete(PersistenceBroker persistenceBroker) throws PersistenceBrokerException { 130 postRemove(); 131 } 132 133 /** 134 * Default implementation of the JPA {@link PostRemove} hook. This implementation currently does nothing, 135 * however sub-classes can override and implement this method if needed. 136 * 137 * <p>This method is currently invoked by the corresponding OJB {@link #afterDelete(PersistenceBroker)} hook. 138 */ 139 @PostRemove 140 protected void postRemove() { 141 // do nothing 142 } 143 144 /** 145 * Implementation of the OJB afterInsert hook which delegates to {@link #postPersist()}. This method is final 146 * because it is recommended that sub-classes override and implement postPersist if they need to take 147 * advantage of this persistence hook. 148 * 149 * @see org.apache.ojb.broker.PersistenceBrokerAware#afterInsert(org.apache.ojb.broker.PersistenceBroker) 150 */ 151 @Override 152 @LegacyDataFramework 153 public final void afterInsert(PersistenceBroker persistenceBroker) throws PersistenceBrokerException { 154 postPersist(); 155 } 156 157 /** 158 * Default implementation of the JPA {@link PostPersist} hook. This implementation currently does nothing, 159 * however sub-classes can override and implement this method if needed. 160 * 161 * <p>This method is currently invoked by the corresponding OJB {@link #afterInsert(PersistenceBroker)} hook. 162 */ 163 @PostPersist 164 protected void postPersist() { 165 // do nothing 166 } 167 168 /** 169 * Implementation of the OJB afterLookup hook which delegates to {@link #postLoad()}. This method is final 170 * because it is recommended that sub-classes override and implement postLoad if they need to take 171 * advantage of this persistence hook. 172 * 173 * @see org.apache.ojb.broker.PersistenceBrokerAware#afterLookup(org.apache.ojb.broker.PersistenceBroker) 174 */ 175 @Override 176 public final void afterLookup(PersistenceBroker persistenceBroker) throws PersistenceBrokerException { 177 postLoad(); 178 } 179 180 /** 181 * Default implementation of the JPA {@link PostLoad} hook. This implementation currently does nothing, 182 * however sub-classes can override and implement this method if needed. 183 * 184 * <p>This method is currently invoked by the corresponding OJB {@link #afterLookup(PersistenceBroker)} hook. 185 */ 186 @PostLoad 187 protected void postLoad() { 188 // do nothing 189 } 190 191 /** 192 * Implementation of the OJB afterUpdate hook which delegates to {@link #postUpdate()}. This method is final 193 * because it is recommended that sub-classes override and implement postUpdate if they need to take 194 * advantage of this persistence hook. 195 * 196 * @see org.apache.ojb.broker.PersistenceBrokerAware#afterUpdate(org.apache.ojb.broker.PersistenceBroker) 197 */ 198 @Override 199 @LegacyDataFramework 200 public final void afterUpdate(PersistenceBroker persistenceBroker) throws PersistenceBrokerException { 201 postUpdate(); 202 } 203 204 /** 205 * Default implementation of the JPA {@link PostUpdate} hook. This implementation currently does nothing, 206 * however sub-classes can override and implement this method if needed. 207 * 208 * <p>This method is currently invoked by the corresponding OJB {@link #afterUpdate(PersistenceBroker)} hook. 209 */ 210 @PostUpdate 211 protected void postUpdate() { 212 // do nothing 213 } 214 215 /** 216 * Implementation of the OJB beforeDelete hook which delegates to {@link #preRemove()}. This method is final 217 * because it is recommended that sub-classes override and implement preRemove if they need to take 218 * advantage of this persistence hook. 219 * 220 * @see org.apache.ojb.broker.PersistenceBrokerAware#beforeDelete(org.apache.ojb.broker.PersistenceBroker) 221 */ 222 @Override 223 @LegacyDataFramework 224 public final void beforeDelete(PersistenceBroker persistenceBroker) throws PersistenceBrokerException { 225 preRemove(); 226 } 227 228 /** 229 * Default implementation of the JPA {@link PreRemove} hook. This implementation currently does nothing, 230 * however sub-classes can implement this method if needed. 231 * 232 * <p>This method is currently invoked by the corresponding OJB {@link #beforeDelete(PersistenceBroker)} hook. 233 */ 234 @PreRemove 235 protected void preRemove() { 236 // do nothing 237 } 238 239 /** 240 * Implementation of the OJB beforeInsert hook which delegates to {@link #prePersist()}. This method is final 241 * because it is recommended that sub-classes override and implement prePersist if they need to take 242 * advantage of this persistence hook. 243 * 244 * @see org.apache.ojb.broker.PersistenceBrokerAware#beforeInsert(org.apache.ojb.broker.PersistenceBroker) 245 */ 246 @Override 247 @LegacyDataFramework 248 public final void beforeInsert(PersistenceBroker persistenceBroker) throws PersistenceBrokerException { 249 //setObjectId(UUID.randomUUID().toString()); 250 setObjectId(null); 251 prePersist(); 252 } 253 254 /** 255 * Default implementation of the JPA {@link PrePersist} hook which generates the unique objectId for this 256 * persistable business object if it does not already have one. Any sub-class which overrides this method 257 * should take care to invoke super.prePersist to ensure that the objectId for this persistable 258 * business object is generated properly. 259 * 260 * <p>This method is currently invoked by the corresponding OJB {@link #beforeInsert(PersistenceBroker)} hook. 261 */ 262 @PrePersist 263 protected void prePersist() { 264 generateAndSetObjectIdIfNeeded(); 265 } 266 267 /** 268 * Implementation of the OJB beforeUpdate hook which delegates to {@link #preUpdate()}. This method is final 269 * because it is recommended that sub-classes override and implement preUpdate if they need to take 270 * advantage of this persistence hook. 271 * 272 * @see org.apache.ojb.broker.PersistenceBrokerAware#beforeUpdate(org.apache.ojb.broker.PersistenceBroker) 273 */ 274 @Override 275 @LegacyDataFramework 276 public final void beforeUpdate(PersistenceBroker persistenceBroker) throws PersistenceBrokerException { 277 preUpdate(); 278 } 279 280 /** 281 * Default implementation of the JPA {@link PreUpdate} hook which generates the unique objectId for this 282 * persistable business object if it does not already have one. Any sub-class which overrides this method 283 * should take care to invoke super.preUpdate to ensure that the objectId for this persistable 284 * business object is generated properly. 285 * 286 * <p>This method is currently invoked by the corresponding OJB {@link #beforeUpdate(PersistenceBroker)} hook. 287 */ 288 @PreUpdate 289 protected void preUpdate() { 290 generateAndSetObjectIdIfNeeded(); 291 } 292 293 /** 294 * If this PersistableBusinessObject does not already have a unique objectId, this method will generate 295 * one and set it's value on this object. 296 */ 297 private void generateAndSetObjectIdIfNeeded() { 298 if (StringUtils.isEmpty(getObjectId())) { 299 setObjectId(UUID.randomUUID().toString()); 300 } 301 } 302 303 /** 304 * getService Refreshes the reference objects from the primitive values. 305 * 306 * @see org.kuali.rice.krad.bo.BusinessObject#refresh() 307 */ 308 @Override 309 public void refresh() { 310 getLegacyDataAdapter().refresh(this); 311 } 312 313 @Override 314 public void refreshNonUpdateableReferences() { 315 getLegacyDataAdapter().refreshNonUpdateableReferences(this); 316 } 317 318 @Override 319 public void refreshReferenceObject(String referenceObjectName) { 320 getLegacyDataAdapter().refreshReferenceObject(this, referenceObjectName); 321 } 322 323 @Override 324 public List<Collection<PersistableBusinessObject>> buildListOfDeletionAwareLists() { 325 return new ArrayList<Collection<PersistableBusinessObject>>(); 326 } 327 328 @Override 329 public void linkEditableUserFields() { 330 // do nothing 331 } 332 333 @Override 334 public PersistableBusinessObjectExtension getExtension() { 335 if ( extension == null 336 && getLegacyDataAdapter().isPersistable(this.getClass())) { 337 try { 338 extension = getLegacyDataAdapter().getExtension(this.getClass()); 339 } catch ( Exception ex ) { 340 LOG.error( "unable to create extension object", ex ); 341 } 342 } 343 return extension; 344 } 345 346 @Override 347 public void setExtension(PersistableBusinessObjectExtension extension) { 348 this.extension = extension; 349 } 350 351 /** 352 * Returns the legacy data adapter for handling legacy KNS and KRAD data and metadata. 353 * 354 * @return the legacy data adapter 355 * @deprecated application code should never use this! Always use KRAD code directly. 356 */ 357 @Deprecated 358 protected static LegacyAppFrameworkAdapterService getLegacyDataAdapter() { 359 return KNSServiceLocator.getLegacyAppFrameworkAdapterService(); 360 } 361 362}