001/*
002 * $RCSfile: Event.java,v $
003 * $Revision: 1.35 $
004 * $Date: 2013/11/08 22:44:44 $
005 *
006 * Copyright 2012, 2013 Cloud Software Group, Inc. ALL RIGHTS RESERVED. 
007 * Cloud Software Group, Inc. Confidential Information
008 */
009
010package com.tibco.xp.runtime;
011
012import com.kabira.platform.ObjectNotUniqueError;
013import com.kabira.platform.ResourceUnavailableException;
014import com.tibco.cep.kernel.model.knowledgebase.DuplicateExtIdException;
015import com.tibco.cep.kernel.service.logging.Level;
016
017/**
018 * Event base class
019 */
020public abstract class Event extends Entity
021{
022    /**
023     * TimeToLiveUnits value, in days.
024     */
025    public static final String  TIME_TO_LIVE_UNITS_DAYS = "DAYS";
026    /**
027     * TimeToLiveUnits value, in hours.
028     */
029    public static final String  TIME_TO_LIVE_UNITS_HOURS = "HOURS";
030    /**
031     * TimeToLiveUnits value, in minutes.
032     */
033    public static final String  TIME_TO_LIVE_UNITS_MINUTES = "MINUTES";
034    /**
035     * TimeToLiveUnits value, in seconds.
036     */
037    public static final String  TIME_TO_LIVE_UNITS_SECONDS = "SECONDS";
038    /**
039     * TimeToLiveUnits value, in milliseconds.
040     */
041    public static final String  TIME_TO_LIVE_UNITS_MILLISECONDS = "MILLISECONDS";
042    
043 
044        /**
045         * Use {@link #assertEvent()} instead.
046         */
047        @Deprecated
048        public final void generate()
049        {
050            assertEvent();
051        }
052        
053        /**
054         * Assert an event.  
055         * <p>
056         * This method starts a new run-to-completion (RTC) 
057         * cycle if one is not already active.  If there is already
058         * an active RTC, this event is added to the current RTC
059         * agenda.
060         * <p>
061         * If this method started a new RTC cycle, it is complete 
062         * when this method returns.  If there is already an active
063         * RTC cycle, this event is just added to the current agenda
064         * and it will be executed at the end of the current 
065         * conflict resolution cycle.
066     * <p>
067     * A new transaction is started if one is not already active.
068         * <p>
069         * RETE working memory is cleared at the end
070         * of the RTC cycle.
071         * @throws ObjectNotUniqueError Duplicate external identifier
072         * @throws ResourceUnavailableException Rules engine not running
073         */
074        protected void assertEvent() throws ObjectNotUniqueError, ResourceUnavailableException
075        {
076            checkActive();
077        setDispatched();
078        updateProperties();
079        
080        try
081        {
082            assertEntity(true);
083        }
084        catch (DuplicateExtIdException e)
085        {
086                TransactionService.log(Level.ERROR, e, e.getLocalizedMessage());
087            throw new ObjectNotUniqueError(e.getLocalizedMessage());
088        }
089        }
090        
091        /**
092         * Use {@link #setPayLoad(PayLoad)} instead.
093         * @param payload Payload
094         * @throws IllegalArgumentException Null payload specified
095         */
096        @Deprecated
097        public final void setPayload(final String payload) throws IllegalArgumentException
098        {
099                enforceDispatchState();
100                
101                if (payload == null)
102                {
103                        throw new IllegalArgumentException("Payload cannot be null");
104                }
105
106                setPayLoad(new PayLoad(payload));
107        }
108        
109        /**
110         * Set the event payload.
111         * <p>
112         * The payload cannot be changed after an event 
113         * has been asserted.
114         *
115         * @param payload       A non-null payload to store in this event.
116         * @throws IllegalArgumentException Null payload specified
117         */
118        public final void setPayLoad(final PayLoad payload) throws IllegalArgumentException
119        {
120                enforceDispatchState();
121                
122                if (payload == null)
123                {
124                        throw new IllegalArgumentException("Payload cannot be null");
125                }
126                updatePayLoad(payload);
127        }
128        
129        @Override
130        public String toString()
131        {
132                StringBuilder value = new StringBuilder(super.toString());
133                
134                value.append("@ttl=");
135                value.append(getTimeToLive());
136                value.append(" ");
137                value.append(getTimeToLiveUnits());
138                value.append("@payload=");
139                value.append(getPayLoad());
140                value.append("&destination=");
141                value.append(getDestination());
142                value.append("&timeridentifier=");
143                value.append(getTimerIdentifier());
144                return value.toString();
145        }
146        
147        /**
148         * Delete this event
149         */
150        public abstract void delete();
151        
152        /**
153         * Use {@link #getPayLoad()} instead.
154         * @return Payload value
155         */
156        @Deprecated
157        public String getPayload()
158        {
159                PayLoad payload = getPayLoad();
160                
161                if (payload == null)
162                {
163                        return null;
164                }
165                byte [ ] value = payload.getValue();
166                return new String(value);
167        }
168        
169        /**
170         * Get the event payload
171         *
172         * @return The payload stored in this event.
173         */
174        public abstract PayLoad getPayLoad();
175        
176        /**
177         * Set the event destination
178         * <p>
179         * The destination cannot be changed after an event 
180         * has been asserted.
181         * <p>
182         * Destination cannot be null.
183         * @param destination Destination value
184         * @throws IllegalArgumentException Illegal destination specified
185         *
186         */
187        public abstract void setDestination(final String destination)
188                        throws IllegalArgumentException;
189        
190        /**
191         * Get the event destination
192         *
193         * @return The destination stored in this event.
194         */
195        public abstract String getDestination();
196
197        /**
198         * Get the retry-on-exception value for this event.
199         * @return Retry on exception value
200         */
201        public abstract Boolean getRetryOnException();
202
203        /**
204         * Get the Time-To-Live value for this event.
205         * @return TTL value
206         */
207        public abstract Long getTimeToLive();
208        
209        /**
210     * Get the Time-To-Live units for this event.
211     * @return TTL units
212     */
213    public abstract String getTimeToLiveUnits();
214    
215        /**
216     * Set retry on exception 
217     * @param retryOnException Retry on exception value
218     */
219    protected abstract void setRetryOnException(final Boolean retryOnException);
220    
221        /**
222         * Update the internal payload
223         * @param payload Payload value
224         */
225        protected abstract void updatePayLoad(final PayLoad payload);
226        
227        /**
228         * Set the time to live for this event
229         * @param timeToLive Time to live value.
230         */
231        protected abstract void setTimeToLive(final Long timeToLive);
232        
233        /**
234         * Set time to live units
235         * @param timeToLiveUnits Time to live units
236         */
237        protected abstract void setTimeToLiveUnits(final String timeToLiveUnits);
238                
239        /**
240         * Get the current dispatch state
241         * @return True if dispatched, false otherwise
242         */
243    protected abstract Boolean getDispatched();
244    
245    /**
246     * Set dispatched to true
247     */
248    protected abstract void setDispatched();
249    
250    /**
251     * Update event handle properties from shared memory
252     */
253    protected abstract void updateProperties();
254    
255        /**
256         * Get the timer identifier for this event
257         * @return Timer identifier or an empty string if not scheduled for expiration
258         */
259        abstract String getTimerIdentifier();
260        
261        /**
262         * Set the timer identifier for this event
263         * @param identifier Timer identifier
264         */
265        abstract void setTimerIdentifier(final String identifier);
266
267    /**
268     * Enforce that setters cannot change fields once event has
269     * been asserted
270     * @throws IllegalStateException Event already asserted
271     */
272        protected final void enforceDispatchState()
273                throws IllegalStateException
274        {
275                if (getDispatched() == true)
276                {
277                        String message = "Cannot set fields in this event because it " +
278                                        "has already been asserted.";
279                        TransactionService.log(Level.ERROR, message);
280                        throw new IllegalStateException(message);
281                }
282        }
283        
284        private static final long serialVersionUID = 2L;
285        protected static final Boolean _DEFAULT_RETRY_ON_EXCEPTION = false;
286        protected static final String _INVALID_TIMER_IDENTIFIER = "";
287        protected static final Long _DEFAULT_TIME_TO_LIVE = 0L;
288        protected static final String _TIME_TO_LIVE_UNITS_DEFAULT = TIME_TO_LIVE_UNITS_DAYS;
289}