Coverage Report - org.kuali.rice.kns.bo.PersistableBusinessObjectBase
 
Classes in this File Line Coverage Branch Coverage Complexity
PersistableBusinessObjectBase
0%
0/127
0%
0/76
2
 
 1  
 /*
 2  
  * Copyright 2007 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.kns.bo;
 17  
 
 18  
 import java.util.ArrayList;
 19  
 import java.util.HashMap;
 20  
 import java.util.Iterator;
 21  
 import java.util.List;
 22  
 import java.util.Map;
 23  
 
 24  
 import javax.persistence.Column;
 25  
 import javax.persistence.MappedSuperclass;
 26  
 import javax.persistence.PrePersist;
 27  
 import javax.persistence.PreUpdate;
 28  
 import javax.persistence.Transient;
 29  
 import javax.persistence.Version;
 30  
 
 31  
 import org.apache.commons.lang.StringUtils;
 32  
 import org.apache.ojb.broker.PersistenceBroker;
 33  
 import org.apache.ojb.broker.PersistenceBrokerException;
 34  
 import org.kuali.rice.core.util.OrmUtils;
 35  
 import org.kuali.rice.kns.service.AttachmentService;
 36  
 import org.kuali.rice.kns.service.KNSServiceLocator;
 37  
 import org.kuali.rice.kns.service.NoteService;
 38  
 import org.kuali.rice.kns.service.PersistenceService;
 39  
 import org.kuali.rice.kns.service.PersistenceStructureService;
 40  
 import org.kuali.rice.kns.util.Guid;
 41  
 
 42  
 /**
 43  
  * Business Object Base Business Object
 44  
  */
 45  
 @MappedSuperclass
 46  
 public abstract class PersistableBusinessObjectBase extends BusinessObjectBase implements PersistableBusinessObject {
 47  
     private static final long serialVersionUID = 1451642350593233282L;
 48  0
         private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PersistableBusinessObjectBase.class);
 49  
     @Version
 50  
     @Column(name="VER_NBR")
 51  
     protected Long versionNumber;
 52  
     @Column(name="OBJ_ID")
 53  
     private String objectId;
 54  
     @Transient
 55  
     private boolean newCollectionRecord;
 56  
     @Transient
 57  
     protected PersistableBusinessObjectExtension extension;
 58  
 
 59  
     // The following support notes on BusinessObjects (including DocumentHeader)
 60  0
     @Transient
 61  
     private List boNotes = null;
 62  
     @Transient
 63  
     private transient Boolean thisNotesSupport;
 64  
     @Transient
 65  0
     private transient static Map<Class<? extends PersistableBusinessObjectBase>,Boolean> notesSupportCache = new HashMap<Class<? extends PersistableBusinessObjectBase>,Boolean>();
 66  
     
 67  
     @Transient
 68  
     private static transient AttachmentService attachmentService;
 69  
     @Transient
 70  
     private static transient PersistenceService persistenceService;
 71  
     @Transient
 72  
     private static transient PersistenceStructureService persistenceStructureService;
 73  
     @Transient
 74  
     private static transient NoteService noteService;
 75  
     
 76  
     // This is only a flag if a @Sequence is used and is set up explicitly on Maint Doc creation
 77  
     @Transient
 78  
     private boolean autoIncrementSet;
 79  
     
 80  0
     public PersistableBusinessObjectBase() {
 81  0
         autoIncrementSet = false;
 82  0
     }
 83  
     
 84  
     public boolean isBoNotesSupport() {
 85  0
         if (thisNotesSupport == null) {
 86  0
             thisNotesSupport = notesSupportCache.get(getClass());
 87  0
             if (thisNotesSupport == null) { // not cached
 88  0
                 if (LOG.isDebugEnabled()) {
 89  0
                     LOG.debug("querying service for notesSupport state: " + getClass().getName());
 90  
                 }
 91  
                 // protect against concurrent modification to the cached map
 92  0
                 synchronized ( notesSupportCache ) {
 93  0
                     thisNotesSupport = supportsBoNotes();
 94  0
                     if (thisNotesSupport == null) {
 95  0
                         thisNotesSupport = Boolean.FALSE;
 96  
                     }
 97  0
                     notesSupportCache.put(getClass(), thisNotesSupport);
 98  0
                                 }
 99  
             }
 100  
         }
 101  
 
 102  0
         return thisNotesSupport;
 103  
     }
 104  
 
 105  
     protected Boolean supportsBoNotes() {
 106  0
         return KNSServiceLocator.getBusinessObjectDictionaryService().areNotesSupported(getClass());
 107  
     }
 108  
 
 109  
     /**
 110  
      * @see org.kuali.rice.kns.bo.Persistable#getVersionNumber()
 111  
      */
 112  
     public Long getVersionNumber() {
 113  0
         return versionNumber;
 114  
     }
 115  
 
 116  
     /**
 117  
      * @see org.kuali.rice.kns.bo.Persistable#setVersionNumber(java.lang.Long)
 118  
      */
 119  
     public void setVersionNumber(Long versionNumber) {
 120  0
         this.versionNumber = versionNumber;
 121  0
     }
 122  
 
 123  
 
 124  
     /**
 125  
      * getter for the guid based object id that is assignable to all objects, in order to support custom attributes a mapping must
 126  
      * also be added to the OJB file and a column must be added to the database for each business object that extension attributes
 127  
      * are supposed to work on.
 128  
      * 
 129  
      * @return
 130  
      */
 131  
     public String getObjectId() {
 132  0
         return objectId;
 133  
     }
 134  
 
 135  
     /**
 136  
      * setter for the guid based object id that is assignable to all objects, in order to support custom attributes a mapping must
 137  
      * also be added to the OJB file and column must be added to the database for each business object that extension attributes are
 138  
      * supposed to work on.
 139  
      * 
 140  
      * @param objectId
 141  
      */
 142  
     public void setObjectId(String objectId) {
 143  0
         this.objectId = objectId;
 144  0
     }
 145  
 
 146  
 
 147  
     /**
 148  
      * Gets the newCollectionRecord attribute.
 149  
      * 
 150  
      * @return Returns the newCollectionRecord.
 151  
      */
 152  
     public boolean isNewCollectionRecord() {
 153  0
         return newCollectionRecord;
 154  
     }
 155  
 
 156  
     /**
 157  
      * Sets the newCollectionRecord attribute value.
 158  
      * 
 159  
      * @param newCollectionRecord The newCollectionRecord to set.
 160  
      */
 161  
     public void setNewCollectionRecord(boolean isNewCollectionRecord) {
 162  0
         this.newCollectionRecord = isNewCollectionRecord;
 163  0
     }
 164  
 
 165  
     public void afterDelete(PersistenceBroker persistenceBroker) throws PersistenceBrokerException {
 166  0
     }
 167  
 
 168  
     public void afterInsert(PersistenceBroker persistenceBroker) throws PersistenceBrokerException {
 169  
             // no need to attempt to load any notes since this is a new object
 170  0
         if (boNotes != null && !boNotes.isEmpty()) {
 171  0
                 if (isBoNotesSupport()) {
 172  0
                 saveNotes();
 173  
 
 174  
                 // move attachments from pending directory
 175  0
                 if (hasNoteAttachments() && StringUtils.isNotEmpty(objectId)) {
 176  0
                     getAttachmentService().moveAttachmentsWherePending(getBoNotes(), objectId);
 177  
                 }
 178  
             }
 179  
         }
 180  0
     }
 181  
 
 182  
     public void afterLookup(PersistenceBroker persistenceBroker) throws PersistenceBrokerException {
 183  0
     }
 184  
 
 185  
     public void afterUpdate(PersistenceBroker persistenceBroker) throws PersistenceBrokerException {
 186  
             // if the bo notes have not been loaded yet, then there is no need to attempt to save them
 187  
             // also, the saveNotes call never attempts to remove notes removed from the note list
 188  
             // so, an empty list will have no affect during the save process
 189  0
         if (boNotes != null && !boNotes.isEmpty()) {
 190  0
                 if (isBoNotesSupport()) {
 191  0
                 saveNotes();
 192  
 
 193  
                 // move attachments from pending directory
 194  0
                 if (hasNoteAttachments() && StringUtils.isNotEmpty(objectId)) {
 195  0
                     getAttachmentService().moveAttachmentsWherePending(getBoNotes(), objectId);
 196  
                 }
 197  
             }
 198  
         }
 199  0
     }
 200  
 
 201  
     public void beforeDelete(PersistenceBroker persistenceBroker) throws PersistenceBrokerException {
 202  0
     }
 203  
 
 204  
     public void beforeInsert(PersistenceBroker persistenceBroker) throws PersistenceBrokerException {
 205  0
         setObjectId(new Guid().toString());
 206  0
     }
 207  
 
 208  
     public void beforeUpdate(PersistenceBroker persistenceBroker) throws PersistenceBrokerException {
 209  0
             beforeUpdate();
 210  0
     }
 211  
     
 212  
     @PrePersist
 213  
     public void beforeInsert() {
 214  0
             if (!isAutoIncrementSet()) {
 215  0
                     OrmUtils.populateAutoIncValue(this, KNSServiceLocator.getEntityManagerFactory().createEntityManager());
 216  0
                     setAutoIncrementSet(true);
 217  
             }
 218  0
             setObjectId(new Guid().toString());
 219  0
     }
 220  
 
 221  
     @PreUpdate
 222  
     public void beforeUpdate() {
 223  0
         if (StringUtils.isEmpty(getObjectId())) {
 224  0
             setObjectId(new Guid().toString());
 225  
         }
 226  0
     }
 227  
     
 228  
     private void retrieveBoNotes() {
 229  0
         boNotes = getNoteService().getByRemoteObjectId(objectId);
 230  0
     }
 231  
 
 232  
     /**
 233  
      * This method is used to save any existing notes
 234  
      */
 235  
     private void saveNotes() {
 236  0
         if (isBoNotesSupport()) {
 237  0
             linkNoteRemoteObjectId();
 238  0
             getNoteService().saveNoteList(getBoNotes());
 239  
         }
 240  0
     }
 241  
 
 242  
     /**
 243  
      * This method links the note to the objectId
 244  
      */
 245  
     private void linkNoteRemoteObjectId() {
 246  0
         List notes = getBoNotes();
 247  0
         if (notes != null && !notes.isEmpty()) {
 248  0
             for (Iterator iter = notes.iterator(); iter.hasNext();) {
 249  0
                 Note note = (Note) iter.next();
 250  0
                 note.setRemoteObjectIdentifier(getObjectId());
 251  0
             }
 252  
         }
 253  0
     }
 254  
 
 255  
 
 256  
     /**
 257  
      * getService Refreshes the reference objects from the primitive values.
 258  
      * 
 259  
      * @see org.kuali.rice.kns.bo.BusinessObject#refresh()
 260  
      */
 261  
     public void refresh() {
 262  0
         getPersistenceService().retrieveNonKeyFields(this);
 263  0
     }
 264  
 
 265  
     /**
 266  
      * @see org.kuali.rice.kns.bo.BusinessObject#refreshNonUpdateableReferences()
 267  
      */
 268  
     public void refreshNonUpdateableReferences() {
 269  0
         getPersistenceService().refreshAllNonUpdatingReferences(this);
 270  0
     }
 271  
 
 272  
         public void refreshReferenceObject(String referenceObjectName) {
 273  0
                 if ( StringUtils.isNotBlank(referenceObjectName) && !StringUtils.equals(referenceObjectName, "extension")) {
 274  0
                         final PersistenceStructureService pss = getPersistenceStructureService();
 275  0
                         if ( pss.hasReference(this.getClass(), referenceObjectName) || pss.hasCollection(this.getClass(), referenceObjectName)) {
 276  0
                     getPersistenceService().retrieveReferenceObject( this, referenceObjectName);
 277  
                         } else {
 278  0
                 LOG.warn( "refreshReferenceObject() called with non-reference property: " + referenceObjectName );
 279  
                         }
 280  
                 }
 281  0
         }
 282  
 
 283  
     /**
 284  
      * @see org.kuali.rice.kns.bo.PersistableBusinessObject#buildListOfDeletionAwareLists()
 285  
      */
 286  
     public List buildListOfDeletionAwareLists() {
 287  0
         return new ArrayList();
 288  
     }
 289  
 
 290  
     public void linkEditableUserFields() {
 291  0
     }
 292  
 
 293  
 
 294  
     private boolean hasNoteAttachments() {
 295  0
         for (Object obj : getBoNotes()) {
 296  0
             Note note = (Note) obj;
 297  0
             if (note.getAttachment() != null) {
 298  0
                 return true;
 299  
 
 300  
             }
 301  0
         }
 302  0
         return false;
 303  
     }
 304  
 
 305  
     public List getBoNotes() {
 306  0
             if ( boNotes == null ) {
 307  0
                         if (isBoNotesSupport()) {
 308  0
                                 retrieveBoNotes();
 309  
                         }
 310  
                         // ensure that the list is not null after this point
 311  0
                         if ( boNotes == null ) {
 312  0
                                 boNotes = new ArrayList(0);
 313  
                         }
 314  
             }
 315  0
         return boNotes;
 316  
     }
 317  
 
 318  
     public void setBoNotes(List boNotes) {
 319  0
         this.boNotes = boNotes;
 320  0
     }
 321  
 
 322  
     /**
 323  
      * return a note if in range, or an empty note if not
 324  
      * 
 325  
      * @param nbr
 326  
      * @return return a note if in range, or an empty note if not
 327  
      */
 328  
     public Note getBoNote(int nbr) {
 329  0
         while (getBoNotes().size() <= nbr) {
 330  0
             getBoNotes().add(new Note());
 331  
         }
 332  
 
 333  0
         Note note = (Note) getBoNotes().get(nbr);
 334  
 
 335  
         // fix the primary key in case this is used for manual deleting
 336  0
         if (note != null && StringUtils.isEmpty(note.getObjectId())) {
 337  0
             note.setRemoteObjectIdentifier(getObjectId());
 338  
         }
 339  
 
 340  0
         return note;
 341  
     }
 342  
 
 343  
     /**
 344  
      * This method adds a note
 345  
      * 
 346  
      * @param note
 347  
      * @return true if note added
 348  
      */
 349  
     public boolean addNote(Note note) {
 350  0
         return getBoNotes().add(note);
 351  
     }
 352  
 
 353  
     public boolean deleteNote(Note note) {
 354  0
         return getBoNotes().remove(note);
 355  
     }
 356  
 
 357  
         public PersistableBusinessObjectExtension getExtension() {
 358  0
                 if ( extension == null ) {
 359  
                         try {
 360  0
                                 Class extensionClass = getPersistenceStructureService().getBusinessObjectAttributeClass( getClass(), "extension" );
 361  0
                                 if ( extensionClass != null ) {
 362  0
                                         extension = (PersistableBusinessObjectExtension)extensionClass.newInstance();
 363  
                                 }
 364  0
                         } catch ( Exception ex ) {
 365  0
                                 LOG.error( "unable to create extension object", ex );
 366  0
                         }
 367  
                 }
 368  0
                 return extension;
 369  
         }
 370  
 
 371  
         public void setExtension(PersistableBusinessObjectExtension extension) {
 372  0
                 this.extension = extension;
 373  0
         }
 374  
 
 375  
         public boolean isAutoIncrementSet() {
 376  0
                 return autoIncrementSet;
 377  
         }
 378  
 
 379  
         public void setAutoIncrementSet(boolean autoIncrementSet) {
 380  0
                 this.autoIncrementSet = autoIncrementSet;
 381  0
         }
 382  
 
 383  
         /**
 384  
          * @return the attachmentService
 385  
          */
 386  
         protected static AttachmentService getAttachmentService() {
 387  0
                 if ( attachmentService == null ) {
 388  0
                         attachmentService = KNSServiceLocator.getAttachmentService();
 389  
                 }
 390  0
                 return attachmentService;
 391  
         }
 392  
 
 393  
         /**
 394  
          * @return the persistenceService
 395  
          */
 396  
         protected static PersistenceService getPersistenceService() {
 397  0
                 if ( persistenceService == null ) {
 398  0
                         persistenceService = KNSServiceLocator.getPersistenceService();
 399  
                 }
 400  0
                 return persistenceService;
 401  
         }
 402  
 
 403  
         protected static PersistenceStructureService getPersistenceStructureService() {
 404  0
                 if ( persistenceStructureService == null ) {
 405  0
                         persistenceStructureService = KNSServiceLocator.getPersistenceStructureService();
 406  
                 }
 407  0
                 return persistenceStructureService;
 408  
         }
 409  
         
 410  
         /**
 411  
          * @return the noteService
 412  
          */
 413  
         protected static NoteService getNoteService() {
 414  0
                 if ( noteService == null ) {
 415  0
                         noteService = KNSServiceLocator.getNoteService();
 416  
                 }
 417  0
                 return noteService;
 418  
         }
 419  
 
 420  
 }