1 /*
2  * hunt-proton: AMQP Protocol library for D programming language.
3  *
4  * Copyright (C) 2018-2019 HuntLabs
5  *
6  * Website: https://www.huntlabs.net/
7  *
8  * Licensed under the Apache-2.0 License.
9  *
10  */
11 
12 module hunt.proton.engine.impl.EventImpl;
13 
14 
15 import hunt.proton.engine.Connection;
16 import hunt.proton.engine.Delivery;
17 import hunt.proton.engine.Event;
18 import hunt.proton.engine.EventType;
19 import hunt.proton.engine.Handler;
20 import hunt.proton.engine.HandlerException;
21 import hunt.proton.engine.Link;
22 import hunt.proton.engine.Receiver;
23 import hunt.proton.engine.Record;
24 import hunt.proton.engine.Sender;
25 import hunt.proton.engine.Session;
26 import hunt.proton.engine.Transport;
27 import hunt.proton.engine.Reactor;
28 import hunt.proton.engine.Selectable;
29 import hunt.proton.engine.Task;
30 //import hunt.proton.reactor.impl.ReactorImpl;
31 import hunt.proton.engine.impl.RecordImpl;
32 import hunt.Exceptions;
33 import hunt.collection.LinkedHashSet;
34 import hunt.proton.engine.impl.TransportImpl;
35 /**
36 
37  * EventImpl
38  *
39  */
40 
41 class EventImpl : Event
42 {
43 
44     EventType type;
45     Object context;
46     EventImpl next;
47     RecordImpl _attachments;// = new RecordImpl();
48 
49     this()
50     {
51         this.type = null;
52         _attachments =  new RecordImpl();
53     }
54 
55     void init(EventType type, Object context)
56     {
57         this.type = type;
58         this.context = context;
59         this._attachments.clear();
60     }
61 
62     void clear()
63     {
64         type = null;
65         context = null;
66         _attachments.clear();
67     }
68 
69 
70     public EventType getEventType()
71     {
72         return type;
73     }
74 
75 
76     public Type getType() {
77         Type t = cast(Type)type;
78         if (t !is null) {
79             return t;
80         }
81         return Type.NON_CORE_EVENT;
82     }
83 
84 
85     public Object getContext()
86     {
87         return context;
88     }
89 
90 
91     public Handler getRootHandler() {
92         implementationMissing(false);
93         return null;
94 
95       //  return ReactorImpl.ROOT.get(this);
96     }
97 
98     private Handler delegated = null;
99 
100      void Idelegate()
101      {
102          implementationMissing(false);
103      }
104 
105     public void dispatch(Handler handler)
106     {
107         Handler old_delegated = delegated;
108         try {
109             delegated = handler;
110             try {
111                 handler.handle(this);
112             } catch(HandlerException handlerException) {
113                 throw handlerException;
114             } catch(RuntimeException runtimeException) {
115                 throw new HandlerException(handler, runtimeException);
116             }
117             delegat();
118         } finally {
119             delegated = old_delegated;
120         }
121     }
122 
123 
124     public void delegat()
125     {
126         if (delegated is null) {
127             return; // short circuit
128         }
129         LinkedHashSet!Handler children = delegated.children();
130         delegated = null;
131         foreach (Handler handler ; children)
132         {
133             dispatch(handler);
134         }
135         //while(children.hasNext()) {
136         //    dispatch(children.next());
137         //}
138     }
139 
140 
141     public void redispatch(EventType as_type, Handler handler)
142     {
143         if (!as_type.isValid()) {
144             throw new IllegalArgumentException("Can only redispatch valid event types");
145         }
146         EventType old = type;
147         try {
148             type = as_type;
149             dispatch(handler);
150         }
151         finally {
152             type = old;
153         }
154     }
155 
156 
157     public Connection getConnection()
158     {
159         Connection conn  = cast(Connection)context;
160         if (conn !is null) {
161             return conn;
162         } else if ( cast(Transport)context !is null) {
163             Transport transport = getTransport();
164             if (transport is null) {
165                 return null;
166             }
167             return (cast(TransportImpl) transport).getConnectionImpl();
168         } else {
169             Session ssn = getSession();
170             if (ssn is null) {
171                 return null;
172             }
173             return ssn.getConnection();
174         }
175     }
176 
177 
178     public Session getSession()
179     {
180         Session session = cast(Session)context;
181         if (session !is null) {
182             return session;
183         } else {
184             Link link = getLink();
185             if (link is null) {
186                 return null;
187             }
188             return link.getSession();
189         }
190     }
191 
192 
193     public Link getLink()
194     {
195         Link link = cast(Link)context;
196         if (link !is null) {
197             return link;
198         } else {
199             Delivery dlv = getDelivery();
200             if (dlv is null) {
201                 return null;
202             }
203             return dlv.getLink();
204         }
205     }
206 
207 
208     public Sender getSender()
209     {
210         Sender sender = cast(Sender)context;
211         if (sender !is null) {
212             return sender;
213         } else {
214             Link link = getLink();
215             Sender s = cast(Sender)link;
216             if (s !is null) {
217                 return s;
218             }
219             return null;
220         }
221     }
222 
223 
224     public Receiver getReceiver()
225     {
226         Receiver rec = cast(Receiver)context;
227         if (rec !is null) {
228             return rec;
229         } else {
230             Link link = getLink();
231             Receiver r = cast(Receiver)link;
232             if (r !is null) {
233                 return r;
234             }
235             return null;
236         }
237     }
238 
239 
240     public Delivery getDelivery()
241     {
242         Delivery del = cast(Delivery)context;
243         if (del !is null) {
244             return del;
245         } else {
246             return null;
247         }
248     }
249 
250 
251     public Transport getTransport()
252     {
253         Transport trsp = cast(Transport)context;
254         if (trsp !is null) {
255             return trsp;
256         } else if (cast(Connection)context !is null) {
257             return (cast(Connection)context).getTransport();
258         } else {
259             Session session = getSession();
260             if (session is null) {
261                 return null;
262             }
263 
264             Connection connection = session.getConnection();
265             if (connection is null) {
266                 return null;
267             }
268 
269             return connection.getTransport();
270         }
271     }
272 
273 
274     public Selectable getSelectable() {
275         Selectable select = cast(Selectable)context;
276         if (select !is null) {
277             return select;
278         } else {
279             return null;
280         }
281     }
282 
283 
284     public Reactor getReactor() {
285 
286         if (cast(Reactor)context !is null) {
287             return cast(Reactor) context;
288         } else if (cast(Task)context !is null) {
289             return (cast(Task)context).getReactor();
290         } else if (cast(Transport)context !is null ) {
291             return (cast(TransportImpl)context).getReactor();
292         } else if (cast(Delivery)context !is null) {
293             return (cast(Delivery)context).getLink().getSession().getConnection().getReactor();
294         } else if (cast(Link)context !is null) {
295             return (cast(Link)context).getSession().getConnection().getReactor();
296         } else if (cast(Session)context !is null) {
297             return (cast(Session)context).getConnection().getReactor();
298         } else if (cast(Connection)context !is null) {
299             return (cast(Connection)context).getReactor();
300         } else if (cast(Selectable)context !is null) {
301             return (cast(Selectable)context).getReactor();
302         }
303         return null;
304     }
305 
306 
307     public Task getTask() {
308         Task tesk = cast(Task)context;
309         if (tesk !is null) {
310             return tesk;
311         } else {
312             return null;
313         }
314     }
315 
316 
317     public Record attachments() {
318         return _attachments;
319     }
320 
321 
322     public Event copy()
323     {
324        EventImpl newEvent = new EventImpl();
325        newEvent.init(type, context);
326        newEvent._attachments.copy(_attachments);
327        return newEvent;
328     }
329 
330     //
331     //public String toString()
332     //{
333     //    return "EventImpl{" + "type=" + type + ", context=" + context + '}';
334     //}
335 
336 
337 }