View Javadoc
1   /**
2    * Copyright 2005-2016 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.kns.service.KNSServiceLocator;
25  import org.kuali.rice.krad.service.KRADServiceLocator;
26  import org.kuali.rice.krad.service.LegacyAppFrameworkAdapterService;
27  import org.kuali.rice.krad.util.LegacyDataFramework;
28  
29  import javax.persistence.Column;
30  import javax.persistence.Embeddable;
31  import javax.persistence.MappedSuperclass;
32  import javax.persistence.PostLoad;
33  import javax.persistence.PostPersist;
34  import javax.persistence.PostRemove;
35  import javax.persistence.PostUpdate;
36  import javax.persistence.PrePersist;
37  import javax.persistence.PreRemove;
38  import javax.persistence.PreUpdate;
39  import javax.persistence.Transient;
40  import javax.persistence.Version;
41  
42  import java.util.ArrayList;
43  import java.util.Collection;
44  import java.util.List;
45  import java.util.UUID;
46  
47  /**
48   * @author Kuali Rice Team (rice.collab@kuali.org)
49   * @deprecated use new KRAD Data framework {@link org.kuali.rice.krad.data.DataObjectService}.
50   *             In this framework, data objects are not required to have a superclass and can
51   *             be POJO's but they can optionally use {@link org.kuali.rice.krad.bo.DataObjectBase}
52   *             to emulate previous functionality.
53   */
54  @Deprecated
55  @MappedSuperclass
56  public abstract class PersistableBusinessObjectBase extends BusinessObjectBase implements PersistableBusinessObject, PersistenceBrokerAware, Versioned, GloballyUnique {
57  
58      /**
59       * EclipseLink static weaving does not weave MappedSuperclass unless an Entity or Embedded is
60       * weaved which uses it, hence this class.
61       */
62      @Embeddable
63      private static final class WeaveMe extends PersistableBusinessObjectBase {}
64  
65      private static final long serialVersionUID = 1451642350593233282L;
66  	private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PersistableBusinessObjectBase.class);
67  
68  	@Version
69      @Column(name = "VER_NBR", length = 8)
70      protected Long versionNumber;
71  
72      @Column(name = "OBJ_ID", length = 36, unique = true)
73      protected String objectId;
74  
75      @Transient protected boolean newCollectionRecord;
76      @Transient protected PersistableBusinessObjectExtension extension;
77  
78      private static transient LegacyAppFrameworkAdapterService legacyDataAdapter;
79  
80      @Override
81      public Long getVersionNumber() {
82          return versionNumber;
83      }
84  
85      @Override
86      public void setVersionNumber(Long versionNumber) {
87          this.versionNumber = versionNumber;
88      }
89  
90      @Override
91      public String getObjectId() {
92          return objectId;
93      }
94  
95      @Override
96      public void setObjectId(String objectId) {
97          this.objectId = objectId;
98      }
99  
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 }