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 }