001/**
002 * Copyright 2005-2016 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.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/ecl2.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 */
016package org.kuali.rice.ken.bo;
017
018import org.apache.commons.collections.CollectionUtils;
019import org.apache.commons.lang.StringUtils;
020import org.hibernate.annotations.GenericGenerator;
021import org.hibernate.annotations.Parameter;
022import org.joda.time.DateTime;
023import org.kuali.rice.ken.api.notification.Notification;
024import org.kuali.rice.ken.api.notification.NotificationContract;
025import org.kuali.rice.ken.api.notification.NotificationRecipient;
026import org.kuali.rice.ken.api.notification.NotificationRecipientContract;
027import org.kuali.rice.ken.api.notification.NotificationSender;
028import org.kuali.rice.ken.api.notification.NotificationSenderContract;
029import org.kuali.rice.ken.util.NotificationConstants;
030import org.kuali.rice.krad.bo.PersistableBusinessObjectBase;
031
032import javax.persistence.Basic;
033import javax.persistence.CascadeType;
034import javax.persistence.Column;
035import javax.persistence.Entity;
036import javax.persistence.FetchType;
037import javax.persistence.GeneratedValue;
038import javax.persistence.Id;
039import javax.persistence.JoinColumn;
040import javax.persistence.Lob;
041import javax.persistence.OneToMany;
042import javax.persistence.OneToOne;
043import javax.persistence.OrderBy;
044import javax.persistence.Table;
045import java.sql.Timestamp;
046import java.util.ArrayList;
047import java.util.List;
048
049/**
050 * This class represents an instace of a notification message that is received by the overall 
051 * system.
052 * @author Kuali Rice Team (rice.collab@kuali.org)
053 */
054@Entity
055@Table(name="KREN_NTFCTN_T")
056public class NotificationBo extends PersistableBusinessObjectBase implements NotificationContract, Lockable {
057   
058    @Id
059    @GeneratedValue(generator="KREN_NTFCTN_S")
060        @GenericGenerator(name="KREN_NTFCTN_S",strategy="org.hibernate.id.enhanced.SequenceStyleGenerator",parameters={
061                        @Parameter(name="sequence_name",value="KREN_NTFCTN_S"),
062                        @Parameter(name="value_column",value="id")
063        })
064        @Column(name="NTFCTN_ID")
065        private Long id;
066    @Column(name="DELIV_TYP", nullable=false)
067        private String deliveryType;
068        @Column(name="CRTE_DTTM", nullable=false)
069        private Timestamp creationDateTimeValue;
070        @Column(name="SND_DTTM", nullable=true)
071        private Timestamp sendDateTimeValue;
072        @Column(name="AUTO_RMV_DTTM", nullable=true)
073        private Timestamp autoRemoveDateTimeValue;
074    @Column(name="TTL", nullable=true)
075        private String title;
076    @Lob
077        @Basic(fetch=FetchType.LAZY)
078        @Column(name="CNTNT", nullable=false)
079        private String content;
080    @Column(name="PROCESSING_FLAG", nullable=false)
081        private String processingFlag;
082        @Column(name="LOCKD_DTTM", nullable=true)
083        private Timestamp lockedDateValue;
084    @Column(name = "DOC_TYP_NM", nullable = true)
085    private String docTypeName;
086    /**
087     * Lock column for OJB optimistic locking
088     */
089//    @Version
090//      @Column(name="VER_NBR")
091//      private Integer lockVerNbr;
092    
093    // object references
094    @OneToOne(fetch=FetchType.EAGER, cascade={CascadeType.REFRESH, CascadeType.DETACH})
095        @JoinColumn(name="PRIO_ID")
096        private NotificationPriorityBo priority;
097    @OneToOne(fetch=FetchType.EAGER, cascade={CascadeType.REFRESH, CascadeType.DETACH})
098        @JoinColumn(name="CNTNT_TYP_ID")
099        private NotificationContentTypeBo contentType;
100    @OneToOne(fetch=FetchType.EAGER, cascade={CascadeType.REFRESH, CascadeType.DETACH})
101        @JoinColumn(name="CHNL_ID")
102        private NotificationChannelBo channel;
103    @OneToOne(fetch=FetchType.EAGER, cascade={CascadeType.REFRESH, CascadeType.DETACH})
104        @JoinColumn(name="PRODCR_ID")
105        private NotificationProducerBo producer;
106    
107    // lists
108    @OneToMany(cascade={CascadeType.ALL},
109           targetEntity=NotificationRecipientBo.class, mappedBy="notification")
110    @OrderBy("id ASC")
111        private List<NotificationRecipientBo> recipients;
112    @OneToMany(cascade={CascadeType.ALL},
113           targetEntity=NotificationSenderBo.class, mappedBy="notification")
114        @OrderBy("id ASC")
115    private List<NotificationSenderBo> senders;
116    
117    /**
118     * Constructs a Notification instance.
119     */
120    public NotificationBo() {
121        recipients = new ArrayList<NotificationRecipientBo>();
122        senders = new ArrayList<NotificationSenderBo>();
123        processingFlag = NotificationConstants.PROCESSING_FLAGS.UNRESOLVED;
124    }
125
126    /**
127     * Returns when this Notification entry was created 
128     * @return when this Notification entry was created
129     */
130    public Timestamp getCreationDateTimeValue() {
131        return creationDateTimeValue;
132    }
133
134    @Override
135    public DateTime getCreationDateTime() {
136        return this.creationDateTimeValue == null ? null : new DateTime(this.creationDateTimeValue);
137    }
138
139    /**
140     * Sets the creation date of this Notification entry
141     * @param created the creation date of this Notification entry
142     */
143    public void setCreationDateTimeValue(Timestamp created) {
144        this.creationDateTimeValue = created;
145    }
146
147    /**
148     * Return value of lock column for OJB optimistic locking
149     * @return value of lock column for OJB optimistic locking
150     */
151 // should discard this method and call super directly
152    public Integer getLockVerNbr() {
153        return Integer.valueOf(super.getVersionNumber().intValue());
154    }
155
156    /**
157     * Set value of lock column for OJB optimistic locking
158     * @param lockVerNbr value of lock column for OJB optimistic locking
159     */
160 // should discard this method and call super directly
161    public void setLockVerNbr(Integer lockVerNbr) {
162        super.setVersionNumber(lockVerNbr.longValue());
163    }
164
165    /**
166     * Gets the recipients attribute. 
167     * @return Returns the recipients.
168     */
169    public List<NotificationRecipientBo> getRecipients() {
170        return recipients;
171    }
172
173    /**
174     * Sets the recipients attribute value.
175     * @param recipients The recipients to set.
176     */
177    public void setRecipients(List<NotificationRecipientBo> recipients) {
178        this.recipients = recipients;
179    }
180
181    /**
182     * Retrieves a recipient at the specified index
183     * @param index the index in the recipients collection
184     * @return the recipient if found or null
185     */
186    public NotificationRecipientBo getRecipient(int index) {
187        return (NotificationRecipientBo) recipients.get(index);
188    }
189    
190    /**
191     * Adds a recipient
192     * @param recipient The recipient to add
193     */
194    public void addRecipient(NotificationRecipientBo recipient) {
195        recipients.add(recipient);
196    }
197
198    /**
199     * Gets the senders attribute. 
200     * @return Returns the senders.
201     */
202    public List<NotificationSenderBo> getSenders() {
203        return senders;
204    }
205
206    /**
207     * Sets the senders attribute value.
208     * @param senders The senders to set.
209     */
210    public void setSenders(List<NotificationSenderBo> senders) {
211        this.senders = senders;
212    }
213
214    /**
215     * Retrieves a sender at the specified index
216     * @param index the index in the senders collection
217     * @return the sender if found or null
218     */
219    public NotificationSenderBo getSender(int index) {
220        return (NotificationSenderBo) senders.get(index);
221    }
222    /**
223     * Adds a sender
224     * @param sender The sender to add
225     */
226    public void addSender(NotificationSenderBo sender) {
227        senders.add(sender);
228    }
229
230    /**
231     * Gets the autoRemoveDateTime attribute. 
232     * @return Returns the autoRemoveDateTime.
233     */
234    public Timestamp getAutoRemoveDateTimeValue() {
235            return this.autoRemoveDateTimeValue;
236    }
237
238    @Override
239    public DateTime getAutoRemoveDateTime() {
240        return this.autoRemoveDateTimeValue == null ? null : new DateTime(this.autoRemoveDateTimeValue);
241    }
242
243    /**
244     * Sets the autoRemoveDateTime attribute value.
245     * @param autoRemoveDateTimeValue The autoRemoveDateTime to set.
246     */
247    public void setAutoRemoveDateTimeValue(Timestamp autoRemoveDateTimeValue) {
248            this.autoRemoveDateTimeValue = autoRemoveDateTimeValue;
249    }
250
251    /**
252     * Gets the channel attribute. 
253     * @return Returns the channel.
254     */
255    public NotificationChannelBo getChannel() {
256            return channel;
257    }
258
259    /**
260     * Sets the channel attribute value.
261     * @param channel The channel to set.
262     */
263    public void setChannel(NotificationChannelBo channel) {
264            this.channel = channel;
265    }
266
267    /**
268     * Gets the content attribute. 
269     * @return Returns the content.
270     */
271    public String getContent() {
272            return content;
273    }
274
275    /**
276     * Sets the content attribute value.
277     * @param content The content to set.
278     */
279    public void setContent(String content) {
280            this.content = content;
281    }
282
283    /**
284     * Gets the contentType attribute. 
285     * @return Returns the contentType.
286     */
287    public NotificationContentTypeBo getContentType() {
288            return contentType;
289    }
290
291    /**
292     * Sets the contentType attribute value.
293     * @param contentType The contentType to set.
294     */
295    public void setContentType(NotificationContentTypeBo contentType) {
296            this.contentType = contentType;
297    }
298
299    /**
300     * Gets the deliveryType attribute. 
301     * @return Returns the deliveryType.
302     */
303    public String getDeliveryType() {
304            return deliveryType;
305    }
306
307    /**
308     * Sets the deliveryType attribute value.
309     * @param deliveryType The deliveryType to set.
310     */
311    public void setDeliveryType(String deliveryType) {
312            this.deliveryType = deliveryType.toUpperCase();
313    }
314
315    /**
316     * Gets the id attribute. 
317     * @return Returns the id.
318     */
319    public Long getId() {
320            return id;
321    }
322
323    /**
324     * Sets the id attribute value.
325     * @param id The id to set.
326     */
327    public void setId(Long id) {
328            this.id = id;
329    }
330
331    /**
332     * Gets the priority attribute. 
333     * @return Returns the priority.
334     */
335    public NotificationPriorityBo getPriority() {
336            return priority;
337    }
338
339    /**
340     * Sets the priority attribute value.
341     * @param priority The priority to set.
342     */
343    public void setPriority(NotificationPriorityBo priority) {
344            this.priority = priority;
345    }
346
347    /**
348     * Gets the producer attribute. 
349     * @return Returns the producer.
350     */
351    public NotificationProducerBo getProducer() {
352            return producer;
353    }
354
355    /**
356     * Sets the producer attribute value.
357     * @param producer The producer to set.
358     */
359    public void setProducer(NotificationProducerBo producer) {
360            this.producer = producer;
361    }
362
363    /**
364     * Gets the sendDateTime attribute. 
365     * @return Returns the sendDateTime.
366     */
367    public Timestamp getSendDateTimeValue() {
368            return this.sendDateTimeValue;
369    }
370
371    @Override
372    public DateTime getSendDateTime() {
373        return this.sendDateTimeValue == null ? null : new DateTime(this.sendDateTimeValue);
374    }
375
376    /**
377     * Sets the sendDateTime attribute value.
378     * @param sendDateTimeValue The sendDateTime to set.
379     */
380    public void setSendDateTimeValue(Timestamp sendDateTimeValue) {
381            this.sendDateTimeValue = sendDateTimeValue;
382    }
383
384    /**
385     * Gets the processingFlag attribute. 
386     * @return Returns the processingFlag.
387     */
388    public String getProcessingFlag() {
389        return processingFlag;
390    }
391
392    /**
393     * Sets the processingFlag attribute value.
394     * @param processingFlag The processingFlag to set.
395     */
396    public void setProcessingFlag(String processingFlag) {
397        this.processingFlag = processingFlag;
398    }
399    
400    /**
401     * Gets the lockedDate attribute. 
402     * @return Returns the lockedDate.
403     */
404    public Timestamp getLockedDateValue() {
405        return this.lockedDateValue;
406    }
407
408    @Override
409    public DateTime getLockedDate() {
410        return this.lockedDateValue == null ? null : new DateTime(this.lockedDateValue);
411    }
412    
413    /**
414     * Sets the lockedDate attribute value.
415     * @param lockedDateValue The lockedDate to set.
416     */
417    public void setLockedDateValue(Timestamp lockedDateValue) {
418        this.lockedDateValue = lockedDateValue;
419    }
420
421    /**
422     * Gets the title
423     * @return the title of this notification
424     */
425    public String getTitle() {
426        return title;
427    }
428
429    /**
430     * Sets the title
431     * @param title the title of this notification
432     */
433    public void setTitle(String title) {
434        this.title = title;
435    }
436
437    /**
438     * This method just uses StringUtils to get at the content of the <message> tag 
439     * that exists in the notification content.
440     * @return String
441     */
442    public String getContentMessage() {
443            return StringUtils.substringBetween(content, NotificationConstants.XML_MESSAGE_CONSTANTS.MESSAGE_OPEN, NotificationConstants.XML_MESSAGE_CONSTANTS.MESSAGE_CLOSE);  
444    }
445
446    /**
447     * {@inheritDoc}
448     */
449    @Override
450    public String getDocTypeName() {
451        return docTypeName;
452    }
453
454    /**
455     * Sets the custom document type name.
456     *
457     * <p>
458     * If null, the system will use the default {@code KualiNotification} document type when routing the notification.
459     * If the document type does not match any document type name in the system, the system behavior is undefined.
460     * </p>
461     *
462     * @param docTypeName document type name of this notification
463     */
464    public void setDocTypeName(String docTypeName) {
465        this.docTypeName = docTypeName;
466    }
467
468    /**
469     * Converts a mutable bo to its immutable counterpart
470     * @param bo the mutable business object
471     * @return the immutable object
472     */
473    public static Notification to(NotificationBo bo) {
474        if (bo == null) {
475            return null;
476        }
477
478        return Notification.Builder.create(bo).build();
479    }
480
481    /**
482     * Converts a immutable object to its mutable counterpart
483     * @param im immutable object
484     * @return the mutable bo
485     */
486    public static NotificationBo from(Notification im) {
487        if (im == null) {
488            return null;
489        }
490
491        NotificationBo bo = new NotificationBo();
492        bo.setId(im.getId());
493        bo.setVersionNumber(im.getVersionNumber());
494        bo.setObjectId(im.getObjectId());
495        bo.setDeliveryType(im.getDeliveryType());
496        bo.setCreationDateTimeValue(im.getCreationDateTime() == null ? null : new Timestamp(im.getCreationDateTime().getMillis()));
497        bo.setSendDateTimeValue(im.getSendDateTime() == null ? null : new Timestamp(im.getSendDateTime().getMillis()));
498        bo.setAutoRemoveDateTimeValue(im.getAutoRemoveDateTime() == null ? null : new Timestamp(im.getAutoRemoveDateTime().getMillis()));
499        bo.setTitle(im.getTitle());
500        bo.setContent(im.getContent());
501        bo.setLockedDateValue(im.getLockedDate() == null ? null : new Timestamp(im.getLockedDate().getMillis()));
502        bo.setDocTypeName(im.getDocTypeName());
503
504        // object references
505        bo.setPriority(NotificationPriorityBo.from(im.getPriority()));
506        bo.setContentType(NotificationContentTypeBo.from(im.getContentType()));
507        bo.setChannel(NotificationChannelBo.from(im.getChannel()));
508        bo.setProducer(NotificationProducerBo.from(im.getProducer()));
509
510        // lists
511        List<NotificationRecipientBo> tempRecipients = new ArrayList<NotificationRecipientBo>();
512        if (CollectionUtils.isNotEmpty(im.getRecipients())) {
513            for (NotificationRecipient recipient : im.getRecipients()) {
514                tempRecipients.add(NotificationRecipientBo.from(recipient));
515            }
516            bo.setRecipients(tempRecipients);
517        }
518        List<NotificationSenderBo> tempSenders = new ArrayList<NotificationSenderBo>();
519        if (CollectionUtils.isNotEmpty(im.getSenders())) {
520            for (NotificationSender sender : im.getSenders()) {
521                tempSenders.add(NotificationSenderBo.from(sender));
522            }
523            bo.setSenders(tempSenders);
524        }
525
526        return bo;
527    }
528}