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.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 }