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.krad.bo; 17 18 import org.apache.commons.lang.StringUtils; 19 import org.apache.ojb.broker.PersistenceBroker; 20 import org.apache.ojb.broker.PersistenceBrokerAware; 21 import org.apache.ojb.broker.PersistenceBrokerException; 22 import org.kuali.rice.core.api.mo.common.GloballyUnique; 23 import org.kuali.rice.core.api.mo.common.Versioned; 24 import org.kuali.rice.krad.service.KRADServiceLocator; 25 import org.kuali.rice.krad.service.LegacyAppFrameworkAdapterService; 26 import org.kuali.rice.krad.util.LegacyDataFramework; 27 28 import javax.persistence.Column; 29 import javax.persistence.Embeddable; 30 import javax.persistence.MappedSuperclass; 31 import javax.persistence.PostLoad; 32 import javax.persistence.PostPersist; 33 import javax.persistence.PostRemove; 34 import javax.persistence.PostUpdate; 35 import javax.persistence.PrePersist; 36 import javax.persistence.PreRemove; 37 import javax.persistence.PreUpdate; 38 import javax.persistence.Transient; 39 import javax.persistence.Version; 40 import java.util.ArrayList; 41 import java.util.Collection; 42 import java.util.List; 43 import java.util.UUID; 44 45 /** 46 * @author Kuali Rice Team (rice.collab@kuali.org) 47 * @deprecated use new KRAD Data framework {@link org.kuali.rice.krad.data.DataObjectService}. 48 * In this framework, data objects are not required to have a superclass and can 49 * be POJO's but they can optionally use {@link org.kuali.rice.krad.bo.DataObjectBase} 50 * to emulate previous functionality. 51 */ 52 @Deprecated 53 @MappedSuperclass 54 public abstract class PersistableBusinessObjectBase extends BusinessObjectBase implements PersistableBusinessObject, PersistenceBrokerAware, Versioned, GloballyUnique { 55 56 /** 57 * EclipseLink static weaving does not weave MappedSuperclass unless an Entity or Embedded is 58 * weaved which uses it, hence this class. 59 */ 60 @Embeddable 61 private static final class WeaveMe extends PersistableBusinessObjectBase {} 62 63 private static final long serialVersionUID = 1451642350593233282L; 64 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PersistableBusinessObjectBase.class); 65 66 @Version 67 @Column(name = "VER_NBR", length = 8) 68 protected Long versionNumber; 69 70 @Column(name = "OBJ_ID", length = 36, unique = true) 71 protected String objectId; 72 73 @Transient protected boolean newCollectionRecord; 74 @Transient protected PersistableBusinessObjectExtension extension; 75 76 private static transient LegacyAppFrameworkAdapterService legacyDataAdapter; 77 78 @Override 79 public Long getVersionNumber() { 80 return versionNumber; 81 } 82 83 @Override 84 public void setVersionNumber(Long versionNumber) { 85 this.versionNumber = versionNumber; 86 } 87 88 @Override 89 public String getObjectId() { 90 return objectId; 91 } 92 93 @Override 94 public void setObjectId(String objectId) { 95 this.objectId = objectId; 96 } 97 98 /** 99 * Gets the newCollectionRecord attribute. 100 * 101 * @return Returns the newCollectionRecord. 102 */ 103 @Override 104 public boolean isNewCollectionRecord() { 105 return newCollectionRecord; 106 } 107 108 /** 109 * Sets the newCollectionRecord attribute value. 110 * 111 * @param isNewCollectionRecord The newCollectionRecord to set. 112 */ 113 @Override 114 public void setNewCollectionRecord(boolean isNewCollectionRecord) { 115 this.newCollectionRecord = isNewCollectionRecord; 116 } 117 118 /** 119 * Implementation of the OJB afterDelete hook which delegates to {@link #postRemove()}. This method is final 120 * because it is recommended that sub-classes override and implement postRemove if they need to take 121 * advantage of this persistence hook. 122 * 123 * @see org.apache.ojb.broker.PersistenceBrokerAware#afterDelete(org.apache.ojb.broker.PersistenceBroker) 124 */ 125 @Override 126 @LegacyDataFramework 127 public final void afterDelete(PersistenceBroker persistenceBroker) throws PersistenceBrokerException { 128 postRemove(); 129 } 130 131 /** 132 * Default implementation of the JPA {@link PostRemove} hook. This implementation currently does nothing, 133 * however sub-classes can override and implement this method if needed. 134 * 135 * <p>This method is currently invoked by the corresponding OJB {@link #afterDelete(PersistenceBroker)} hook. 136 */ 137 @PostRemove 138 protected void postRemove() { 139 // do nothing 140 } 141 142 /** 143 * Implementation of the OJB afterInsert hook which delegates to {@link #postPersist()}. This method is final 144 * because it is recommended that sub-classes override and implement postPersist if they need to take 145 * advantage of this persistence hook. 146 * 147 * @see org.apache.ojb.broker.PersistenceBrokerAware#afterInsert(org.apache.ojb.broker.PersistenceBroker) 148 */ 149 @Override 150 @LegacyDataFramework 151 public final void afterInsert(PersistenceBroker persistenceBroker) throws PersistenceBrokerException { 152 postPersist(); 153 } 154 155 /** 156 * Default implementation of the JPA {@link PostPersist} hook. This implementation currently does nothing, 157 * however sub-classes can override and implement this method if needed. 158 * 159 * <p>This method is currently invoked by the corresponding OJB {@link #afterInsert(PersistenceBroker)} hook. 160 */ 161 @PostPersist 162 protected void postPersist() { 163 // do nothing 164 } 165 166 /** 167 * Implementation of the OJB afterLookup hook which delegates to {@link #postLoad()}. This method is final 168 * because it is recommended that sub-classes override and implement postLoad if they need to take 169 * advantage of this persistence hook. 170 * 171 * @see org.apache.ojb.broker.PersistenceBrokerAware#afterLookup(org.apache.ojb.broker.PersistenceBroker) 172 */ 173 @Override 174 public final void afterLookup(PersistenceBroker persistenceBroker) throws PersistenceBrokerException { 175 postLoad(); 176 } 177 178 /** 179 * Default implementation of the JPA {@link PostLoad} hook. This implementation currently does nothing, 180 * however sub-classes can override and implement this method if needed. 181 * 182 * <p>This method is currently invoked by the corresponding OJB {@link #afterLookup(PersistenceBroker)} hook. 183 */ 184 @PostLoad 185 protected void postLoad() { 186 // do nothing 187 } 188 189 /** 190 * Implementation of the OJB afterUpdate hook which delegates to {@link #postUpdate()}. This method is final 191 * because it is recommended that sub-classes override and implement postUpdate if they need to take 192 * advantage of this persistence hook. 193 * 194 * @see org.apache.ojb.broker.PersistenceBrokerAware#afterUpdate(org.apache.ojb.broker.PersistenceBroker) 195 */ 196 @Override 197 @LegacyDataFramework 198 public final void afterUpdate(PersistenceBroker persistenceBroker) throws PersistenceBrokerException { 199 postUpdate(); 200 } 201 202 /** 203 * Default implementation of the JPA {@link PostUpdate} hook. This implementation currently does nothing, 204 * however sub-classes can override and implement this method if needed. 205 * 206 * <p>This method is currently invoked by the corresponding OJB {@link #afterUpdate(PersistenceBroker)} hook. 207 */ 208 @PostUpdate 209 protected void postUpdate() { 210 // do nothing 211 } 212 213 /** 214 * Implementation of the OJB beforeDelete hook which delegates to {@link #preRemove()}. This method is final 215 * because it is recommended that sub-classes override and implement preRemove if they need to take 216 * advantage of this persistence hook. 217 * 218 * @see org.apache.ojb.broker.PersistenceBrokerAware#beforeDelete(org.apache.ojb.broker.PersistenceBroker) 219 */ 220 @Override 221 @LegacyDataFramework 222 public final void beforeDelete(PersistenceBroker persistenceBroker) throws PersistenceBrokerException { 223 preRemove(); 224 } 225 226 /** 227 * Default implementation of the JPA {@link PreRemove} hook. This implementation currently does nothing, 228 * however sub-classes can implement this method if needed. 229 * 230 * <p>This method is currently invoked by the corresponding OJB {@link #beforeDelete(PersistenceBroker)} hook. 231 */ 232 @PreRemove 233 protected void preRemove() { 234 // do nothing 235 } 236 237 /** 238 * Implementation of the OJB beforeInsert hook which delegates to {@link #prePersist()}. This method is final 239 * because it is recommended that sub-classes override and implement prePersist if they need to take 240 * advantage of this persistence hook. 241 * 242 * @see org.apache.ojb.broker.PersistenceBrokerAware#beforeInsert(org.apache.ojb.broker.PersistenceBroker) 243 */ 244 @Override 245 @LegacyDataFramework 246 public final void beforeInsert(PersistenceBroker persistenceBroker) throws PersistenceBrokerException { 247 //setObjectId(UUID.randomUUID().toString()); 248 setObjectId(null); 249 prePersist(); 250 } 251 252 /** 253 * Default implementation of the JPA {@link PrePersist} hook which generates the unique objectId for this 254 * persistable business object if it does not already have one. Any sub-class which overrides this method 255 * should take care to invoke super.prePersist to ensure that the objectId for this persistable 256 * business object is generated properly. 257 * 258 * <p>This method is currently invoked by the corresponding OJB {@link #beforeInsert(PersistenceBroker)} hook. 259 */ 260 @PrePersist 261 protected void prePersist() { 262 generateAndSetObjectIdIfNeeded(); 263 } 264 265 /** 266 * Implementation of the OJB beforeUpdate hook which delegates to {@link #preUpdate()}. This method is final 267 * because it is recommended that sub-classes override and implement preUpdate if they need to take 268 * advantage of this persistence hook. 269 * 270 * @see org.apache.ojb.broker.PersistenceBrokerAware#beforeUpdate(org.apache.ojb.broker.PersistenceBroker) 271 */ 272 @Override 273 @LegacyDataFramework 274 public final void beforeUpdate(PersistenceBroker persistenceBroker) throws PersistenceBrokerException { 275 preUpdate(); 276 } 277 278 /** 279 * Default implementation of the JPA {@link PreUpdate} hook which generates the unique objectId for this 280 * persistable business object if it does not already have one. Any sub-class which overrides this method 281 * should take care to invoke super.preUpdate to ensure that the objectId for this persistable 282 * business object is generated properly. 283 * 284 * <p>This method is currently invoked by the corresponding OJB {@link #beforeUpdate(PersistenceBroker)} hook. 285 */ 286 @PreUpdate 287 protected void preUpdate() { 288 generateAndSetObjectIdIfNeeded(); 289 } 290 291 /** 292 * If this PersistableBusinessObject does not already have a unique objectId, this method will generate 293 * one and set it's value on this object. 294 */ 295 private void generateAndSetObjectIdIfNeeded() { 296 if (StringUtils.isEmpty(getObjectId())) { 297 setObjectId(UUID.randomUUID().toString()); 298 } 299 } 300 301 /** 302 * getService Refreshes the reference objects from the primitive values. 303 * 304 * @see org.kuali.rice.krad.bo.BusinessObject#refresh() 305 */ 306 @Override 307 public void refresh() { 308 getLegacyDataAdapter().refresh(this); 309 } 310 311 @Override 312 public void refreshNonUpdateableReferences() { 313 getLegacyDataAdapter().refreshNonUpdateableReferences(this); 314 } 315 316 @Override 317 public void refreshReferenceObject(String referenceObjectName) { 318 getLegacyDataAdapter().refreshReferenceObject(this, referenceObjectName); 319 } 320 321 @Override 322 public List<Collection<PersistableBusinessObject>> buildListOfDeletionAwareLists() { 323 return new ArrayList<Collection<PersistableBusinessObject>>(); 324 } 325 326 @Override 327 public void linkEditableUserFields() { 328 // do nothing 329 } 330 331 @Override 332 public PersistableBusinessObjectExtension getExtension() { 333 if ( extension == null 334 && getLegacyDataAdapter().isPersistable(this.getClass())) { 335 try { 336 extension = getLegacyDataAdapter().getExtension(this.getClass()); 337 } catch ( Exception ex ) { 338 LOG.error( "unable to create extension object", ex ); 339 } 340 } 341 return extension; 342 } 343 344 @Override 345 public void setExtension(PersistableBusinessObjectExtension extension) { 346 this.extension = extension; 347 } 348 349 /** 350 * Returns the legacy data adapter for handling legacy KNS and KRAD data and metadata. 351 * 352 * @return the legacy data adapter 353 * @deprecated application code should never use this! Always use KRAD code directly. 354 */ 355 @Deprecated 356 protected static LegacyAppFrameworkAdapterService getLegacyDataAdapter() { 357 return KRADServiceLocator.getLegacyAppFrameworkAdapterService(); 358 } 359 360 }