001/*
002 * $RCSfile: NonTransient.java,v $
003 * $Revision: 1.19.2.4 $
004 * $Date: 2015/05/04 16:22:51 $
005 *
006 * Copyright 2013 Cloud Software Group, Inc. ALL RIGHTS RESERVED. 
007 * Cloud Software Group, Inc. Confidential Information
008 */
009package com.tibco.xp.runtime;
010
011import com.kabira.platform.ManagedObject;
012import com.kabira.platform.ObjectNotUniqueError;
013import com.kabira.platform.ResourceUnavailableException;
014import com.kabira.platform.annotation.ByReference;
015import com.kabira.platform.annotation.ByValue;
016import com.kabira.platform.annotation.Managed;
017import com.tibco.cep.runtime.model.event.EventContext;
018import com.tibco.cep.runtime.model.event.impl.SimpleEventImpl;
019
020/**
021 * Base class for non-transient events
022 * <p>
023 * A non-transient event is one that has a TTL != 0.
024 * <p>
025 * Events with a TTL &gt; 0 have an expiration timer started.
026 * When the expiration timer fires, the event is removed 
027 * from shared memory
028 * <p>
029 * Events with a TTL &lt; 0 do not have an expiration timer 
030 * started.  These events remain in shared memory until
031 * explicitly deleted by the application.
032 */
033@Managed
034public abstract class NonTransient extends Event 
035{
036        /**
037         * Java constructor
038         */
039        protected NonTransient()
040        {
041        }
042        
043        /**
044         * Rule or Rule Function constructor
045         * @param id Unique identifier
046         */
047        protected NonTransient(long id)
048        {
049            register(id);
050        }
051        
052        @Override
053        public String toString()
054        {
055                StringBuilder value = new StringBuilder(super.toString());
056
057                value.append("&context=");
058                value.append(NonTransient.getChannelContext(this));
059                value.append("&objectreference=");
060                value.append(ManagedObject.objectToReference(this));
061                return value.toString();
062        }
063        
064        /**
065         * Delete this event.
066         * <p>
067         * If this event currently has a TTL expiration timer
068         * scheduled, the timer is canceled.
069         */
070        @Override
071        public final void delete()
072        {
073                if (getTimerIdentifier().equals(_INVALID_TIMER_IDENTIFIER) == false)
074                {
075                        assert TransactionService.getInstance() != null : this;
076                        TransactionService.getInstance().cancelExpirationTimer(this);
077                }
078                
079                //
080                //      Delete the event
081                //
082                ManagedObject.delete(this);
083        }
084        
085        @Override
086        public final Boolean getRetryOnException() 
087        {
088                return m_retryOnException;
089        }
090
091        @Override
092        public final Long getTimeToLive() 
093        {
094                return m_timeToLive;
095        }
096
097        @Override
098        public final String getTimeToLiveUnits() 
099        {
100                return m_timeToLiveUnits;
101        }
102        
103        @Override
104        public final void assertEvent() throws ObjectNotUniqueError, ResourceUnavailableException
105        {
106                // TODO - Work-around for FLUENCY-5593. 
107                super.assertEvent();
108        }
109        
110        /**
111         * Update user properties from shared memory
112         * @param eventImpl Event handle to update
113         */
114        protected abstract void updateUserProperties(SimpleEventImpl eventImpl);
115
116        @Override
117        protected final void setRetryOnException(Boolean retryOnException) 
118        {
119                m_retryOnException = retryOnException;
120        }
121
122        @Override
123        public final PayLoad getPayLoad() 
124        {
125                return m_payload;
126        }
127        
128        @Override
129        public final void setDestination(final String destination) 
130        {
131                enforceDispatchState();
132                
133                if (destination == null)
134                {
135                        throw new IllegalArgumentException("Destination cannot be null");
136                }
137                
138                m_destination = destination;
139        }
140        
141        @Override
142        public final String getDestination() 
143        {
144                return m_destination;
145        }
146        
147        @Override
148        protected final void updatePayLoad(PayLoad payload) 
149        {
150                m_payload = payload;
151        }
152
153        @Override
154        protected final void setTimeToLive(Long timeToLive) 
155        {
156                assert timeToLive != 0 : this;
157                m_timeToLive = timeToLive;
158        }
159
160        @Override
161        protected final void setTimeToLiveUnits(String timeToLiveUnits) 
162        {
163                m_timeToLiveUnits = timeToLiveUnits;
164        }
165
166        @Override
167        protected final Boolean getDispatched() 
168        {
169                return m_dispatched;
170        }
171
172        @Override
173        protected final void setDispatched() 
174        {
175                m_dispatched = true;
176        }
177        
178        @Override
179        protected final void updateProperties()
180        {
181                assert EntityProxy.getProxy(this) instanceof EventProxy : this;
182        assert getHandle(false) instanceof SimpleEventImpl : this;
183        
184        EventProxy proxy = (EventProxy)EntityProxy.getProxy(this);
185        SimpleEventImpl handle = (SimpleEventImpl) getHandle(false);
186
187                proxy.updateMetaProperties(handle);
188                updateUserProperties(handle);
189                
190                //
191                //      Start TTL timer
192                //
193                assert TransactionService.getInstance() != null : this;
194                TransactionService.getInstance().scheduleEvent(this);           
195        }
196    
197        /**
198         * Get the channel context for an event
199         * @param event Event event
200         * @return Channel context for this event, may be null
201         * <p>
202         * N.B. This method is static to prevent it from being dispatched
203         * on distributed objects since it is accessing local POJOs
204         */
205        protected static final EventContext getChannelContext(NonTransient event) 
206        {
207                assert event != null;
208                return event.m_context;
209        }
210
211        /**
212         * Set the channel context for an event
213         * @param event Event
214         * @param context Channel context to set, may be null
215         * <p>
216         * N.B. This method is static to prevent it from being dispatched
217         * on distributed objects since it is accessing local POJOs
218         */
219        protected static final void setChannelContext(NonTransient event, EventContext context) 
220        {
221                assert event != null;
222                event.m_context = context;
223        }
224        
225        @Override
226        final String getTimerIdentifier()
227        {
228                return m_timerIdentifier;
229        }
230        
231        @Override
232        final void setTimerIdentifier(final String identifier)
233        {
234                assert getTimeToLive() != 0 : this;
235                assert identifier != null : this;
236                m_timerIdentifier = identifier;
237        }
238
239        private boolean m_dispatched = false;
240        private boolean m_retryOnException = _DEFAULT_RETRY_ON_EXCEPTION;
241        private long    m_timeToLive = _DEFAULT_TIME_TO_LIVE;
242        private String  m_timeToLiveUnits = _TIME_TO_LIVE_UNITS_DEFAULT;
243        private String  m_destination = null;
244        @ByValue
245        private PayLoad m_payload = null;
246        @ByReference
247        private EventContext m_context = null;
248        private String m_timerIdentifier = _INVALID_TIMER_IDENTIFIER;
249        private static final long serialVersionUID = 3L;
250}