001: /*
002: * Copyright 2007 The Kuali Foundation.
003: *
004: * Licensed under the Educational Community License, Version 1.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.opensource.org/licenses/ecl1.php
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.kuali.core.bo;
017:
018: import java.util.ArrayList;
019: import java.util.HashMap;
020: import java.util.Iterator;
021: import java.util.List;
022: import java.util.Map;
023:
024: import org.apache.commons.lang.StringUtils;
025: import org.apache.ojb.broker.PersistenceBroker;
026: import org.apache.ojb.broker.PersistenceBrokerException;
027: import org.kuali.core.util.Guid;
028: import org.kuali.rice.KNSServiceLocator;
029:
030: /**
031: * Business Object Base Business Object
032: */
033: public abstract class PersistableBusinessObjectBase extends
034: BusinessObjectBase implements PersistableBusinessObject {
035: private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger
036: .getLogger(PersistableBusinessObjectBase.class);
037: protected Long versionNumber;
038: private String objectId;
039: private boolean newCollectionRecord;
040: private PersistableBusinessObjectExtension extension;
041:
042: // The following support notes on BusinessObjects (including DocumentHeader)
043: private List boNotes = new ArrayList();
044: private transient Boolean this NotesSupport;
045: private transient static Map notesSupport;
046:
047: public boolean isBoNotesSupport() {
048: if (this NotesSupport == null) {
049: if (notesSupport == null) {
050: notesSupport = new HashMap();
051: }
052:
053: this NotesSupport = (Boolean) notesSupport.get(getClass());
054: if (this NotesSupport == null) { // not cached
055: if (LOG.isDebugEnabled()) {
056: LOG
057: .debug("querying service for notesSupport state: "
058: + getClass().getName());
059: }
060: this NotesSupport = supportsBoNotes();
061: if (this NotesSupport == null)
062: this NotesSupport = Boolean.FALSE;
063: notesSupport.put(getClass(), this NotesSupport);
064: }
065: }
066:
067: return this NotesSupport.booleanValue();
068: }
069:
070: protected Boolean supportsBoNotes() {
071: return KNSServiceLocator.getBusinessObjectDictionaryService()
072: .areNotesSupported(getClass());
073: }
074:
075: /**
076: * @see org.kuali.core.bo.Persistable#getVersionNumber()
077: */
078: public Long getVersionNumber() {
079: return versionNumber;
080: }
081:
082: /**
083: * @see org.kuali.core.bo.Persistable#setVersionNumber(java.lang.Long)
084: */
085: public void setVersionNumber(Long versionNumber) {
086: this .versionNumber = versionNumber;
087: }
088:
089: /**
090: * getter for the guid based object id that is assignable to all objects, in order to support custom attributes a mapping must
091: * also be added to the OJB file and a column must be added to the database for each business object that extension attributes
092: * are supposed to work on.
093: *
094: * @return
095: */
096: public String getObjectId() {
097: return objectId;
098: }
099:
100: /**
101: * setter for the guid based object id that is assignable to all objects, in order to support custom attributes a mapping must
102: * also be added to the OJB file and column must be added to the database for each business object that extension attributes are
103: * supposed to work on.
104: *
105: * @param objectId
106: */
107: public void setObjectId(String objectId) {
108: this .objectId = objectId;
109: }
110:
111: /**
112: * Gets the newCollectionRecord attribute.
113: *
114: * @return Returns the newCollectionRecord.
115: */
116: public boolean isNewCollectionRecord() {
117: return newCollectionRecord;
118: }
119:
120: /**
121: * Sets the newCollectionRecord attribute value.
122: *
123: * @param newCollectionRecord The newCollectionRecord to set.
124: */
125: public void setNewCollectionRecord(boolean isNewCollectionRecord) {
126: this .newCollectionRecord = isNewCollectionRecord;
127: }
128:
129: public void afterDelete(PersistenceBroker persistenceBroker)
130: throws PersistenceBrokerException {
131: }
132:
133: public void afterInsert(PersistenceBroker persistenceBroker)
134: throws PersistenceBrokerException {
135: if (isBoNotesSupport()) {
136: if (!boNotes.isEmpty()) {
137: saveNotes();
138:
139: // move attachments from pending directory
140: if (this .hasNoteAttachments()
141: && StringUtils.isNotEmpty(objectId)) {
142: KNSServiceLocator.getAttachmentService()
143: .moveAttachmentsWherePending(boNotes,
144: objectId);
145: }
146: }
147: }
148: }
149:
150: public void afterLookup(PersistenceBroker persistenceBroker)
151: throws PersistenceBrokerException {
152: if (isBoNotesSupport()) {
153: retrieveBoNotes();
154: }
155: }
156:
157: public void afterUpdate(PersistenceBroker persistenceBroker)
158: throws PersistenceBrokerException {
159: if (isBoNotesSupport()) {
160: if (!boNotes.isEmpty()) {
161: saveNotes();
162:
163: // move attachments from pending directory
164: if (this .hasNoteAttachments()
165: && StringUtils.isNotEmpty(objectId)) {
166: KNSServiceLocator.getAttachmentService()
167: .moveAttachmentsWherePending(boNotes,
168: objectId);
169: }
170: }
171: }
172: }
173:
174: public void beforeDelete(PersistenceBroker persistenceBroker)
175: throws PersistenceBrokerException {
176: }
177:
178: public void beforeInsert(PersistenceBroker persistenceBroker)
179: throws PersistenceBrokerException {
180: this .setObjectId(new Guid().toString());
181: }
182:
183: public void beforeUpdate(PersistenceBroker persistenceBroker)
184: throws PersistenceBrokerException {
185: if (StringUtils.isEmpty(this .getObjectId())) {
186: this .setObjectId(new Guid().toString());
187: }
188: }
189:
190: private void retrieveBoNotes() {
191: this .boNotes = KNSServiceLocator.getNoteService()
192: .getByRemoteObjectId(this .objectId);
193: }
194:
195: /**
196: * This method is used to save any existing notes
197: */
198: private void saveNotes() {
199: if (isBoNotesSupport()) {
200: linkNoteRemoteObjectId();
201: KNSServiceLocator.getNoteService().saveNoteList(
202: this .getBoNotes());
203: }
204: }
205:
206: /**
207: * This method links the note to the objectId
208: */
209: private void linkNoteRemoteObjectId() {
210: List notes = getBoNotes();
211: if (notes != null && !notes.isEmpty()) {
212: for (Iterator iter = notes.iterator(); iter.hasNext();) {
213: Note note = (Note) iter.next();
214: note.setRemoteObjectIdentifier(getObjectId());
215: }
216: }
217: }
218:
219: /**
220: * getService Refreshes the reference objects from the primitive values.
221: *
222: * @see org.kuali.core.bo.BusinessObject#refresh()
223: */
224: public void refresh() {
225: KNSServiceLocator.getPersistenceService().retrieveNonKeyFields(
226: this );
227: }
228:
229: /**
230: * @see org.kuali.core.bo.BusinessObject#refreshNonUpdateableReferences()
231: */
232: public void refreshNonUpdateableReferences() {
233: KNSServiceLocator.getPersistenceService()
234: .refreshAllNonUpdatingReferences(this );
235: }
236:
237: /**
238: * Refreshes the reference objects and non-key fields using the primitive values; only if the object is "empty" - i.e. objectId
239: * is null or empty string.
240: */
241: public void refreshIfEmpty() {
242: if (StringUtils.isEmpty(this .getObjectId())) {
243: this .refresh();
244: }
245: }
246:
247: public void refreshReferenceObject(String referenceObjectName) {
248: KNSServiceLocator.getPersistenceService()
249: .retrieveReferenceObject(this , referenceObjectName);
250: }
251:
252: /**
253: * @see org.kuali.core.bo.PersistableBusinessObject#buildListOfDeletionAwareLists()
254: */
255: public List buildListOfDeletionAwareLists() {
256: return new ArrayList();
257: }
258:
259: public void linkEditableUserFields() {
260: }
261:
262: private boolean hasNoteAttachments() {
263: for (Object obj : this .boNotes) {
264: Note note = (Note) obj;
265: if (note.getAttachment() != null) {
266: return true;
267:
268: }
269: }
270: return false;
271: }
272:
273: public List getBoNotes() {
274: return boNotes;
275: }
276:
277: public void setBoNotes(List boNotes) {
278: this .boNotes = boNotes;
279: }
280:
281: /**
282: * return a note if in range, or an empty note if not
283: *
284: * @param nbr
285: * @return return a note if in range, or an empty note if not
286: */
287: public Note getBoNote(int nbr) {
288: while (getBoNotes().size() <= nbr) {
289: getBoNotes().add(new Note());
290: }
291:
292: Note note = (Note) this .getBoNotes().get(nbr);
293:
294: // fix the primary key in case this is used for manual deleting
295: if (note != null && StringUtils.isEmpty(note.getObjectId())) {
296: note.setRemoteObjectIdentifier(getObjectId());
297: }
298:
299: return note;
300: }
301:
302: /**
303: * This method adds a note
304: *
305: * @param note
306: * @return true if note added
307: */
308: public boolean addNote(Note note) {
309: return this .getBoNotes().add(note);
310: }
311:
312: public boolean deleteNote(Note note) {
313: return this .getBoNotes().remove(note);
314: }
315:
316: public PersistableBusinessObjectExtension getExtension() {
317: if (extension == null) {
318: try {
319: Class extensionClass = KNSServiceLocator
320: .getPersistenceStructureService()
321: .getBusinessObjectAttributeClass(
322: this .getClass(), "extension");
323: if (extensionClass != null) {
324: extension = (PersistableBusinessObjectExtension) extensionClass
325: .newInstance();
326: }
327: } catch (Exception ex) {
328: LOG.error("unable to create extension object", ex);
329: }
330: }
331: return extension;
332: }
333:
334: public void setExtension(
335: PersistableBusinessObjectExtension extension) {
336: this.extension = extension;
337: }
338:
339: }
|