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.EndpointImpl;
13 
14 import hunt.proton.amqp.transport.ErrorCondition;
15 import hunt.proton.engine.EndpointState;
16 import hunt.proton.engine.Event;
17 import hunt.proton.engine.ProtonJEndpoint;
18 import hunt.proton.engine.Record;
19 import hunt.proton.engine.impl.RecordImpl;
20 import hunt.proton.engine.impl.ConnectionImpl;
21 import hunt.proton.engine.impl.TransportImpl;
22 
23 import hunt.Exceptions;
24 import hunt.logging.ConsoleLogger;
25 
26 /**
27  * 
28  */
29 class EndpointImpl : ProtonJEndpoint {
30     private EndpointState _localState = EndpointState.UNINITIALIZED;
31     private EndpointState _remoteState = EndpointState.UNINITIALIZED;
32     private ErrorCondition _localError; //= new ErrorCondition();
33     private ErrorCondition _remoteError; // = new ErrorCondition();
34     private bool _modified;
35     private EndpointImpl _transportNext;
36     private EndpointImpl _transportPrev;
37     private Object _context;
38     private Record _attachments; //= new RecordImpl();
39 
40     private int refcount = 1;
41     bool freed = false;
42 
43     this() {
44         _localError = new ErrorCondition();
45         _remoteError = new ErrorCondition();
46         _attachments = new RecordImpl();
47     }
48 
49     void incref() {
50         refcount++;
51     }
52 
53     void decref() {
54         refcount--;
55         if (refcount == 0) {
56             postFinal();
57         } else if (refcount < 0) {
58             throw new IllegalStateException();
59         }
60     }
61 
62     abstract void postFinal();
63 
64     abstract void localOpen();
65 
66     abstract void localClose();
67 
68     void open() {
69         if (getLocalState() != EndpointState.ACTIVE) {
70             _localState = EndpointState.ACTIVE;
71             localOpen();
72             modified();
73         }
74     }
75 
76     void close() {
77         if (getLocalState() != EndpointState.CLOSED) {
78             _localState = EndpointState.CLOSED;
79             localClose();
80             modified();
81         }
82     }
83 
84     EndpointState getLocalState() {
85         return _localState;
86     }
87 
88     EndpointState getRemoteState() {
89         return _remoteState;
90     }
91 
92     ErrorCondition getCondition() {
93         return _localError;
94     }
95 
96     void setCondition(ErrorCondition condition) {
97         if (condition !is null) {
98             _localError.copyFrom(condition);
99         } else {
100             _localError.clear();
101         }
102     }
103 
104     ErrorCondition getRemoteCondition() {
105         return _remoteError;
106     }
107 
108     void setLocalState(EndpointState localState) {
109         _localState = localState;
110     }
111 
112     void setRemoteState(EndpointState remoteState) {
113         // TODO - check state change legal
114         _remoteState = remoteState;
115     }
116 
117     void modified() {
118         modified(true);
119     }
120 
121     void modified(bool emit) {
122         if (!_modified) {
123             _modified = true;
124             getConnectionImpl().addModified(this);
125         }
126 
127         if (emit) {
128             ConnectionImpl conn = getConnectionImpl();
129             TransportImpl trans = conn.getTransport();
130             if (trans !is null) {
131                 conn.put(Type.TRANSPORT, trans);
132             }
133         }
134     }
135 
136     protected abstract ConnectionImpl getConnectionImpl();
137 
138     void clearModified() {
139         if (_modified) {
140             _modified = false;
141             getConnectionImpl().removeModified(this);
142         }
143     }
144 
145     bool isModified() {
146         return _modified;
147     }
148 
149     EndpointImpl transportNext() {
150         return _transportNext;
151     }
152 
153     EndpointImpl transportPrev() {
154         return _transportPrev;
155     }
156 
157     abstract void doFree();
158 
159     void free() {
160         if (freed)
161             return;
162         freed = true;
163 
164         doFree();
165         decref();
166     }
167 
168     void setTransportNext(EndpointImpl transportNext) {
169         _transportNext = transportNext;
170     }
171 
172     void setTransportPrev(EndpointImpl transportPrevious) {
173         _transportPrev = transportPrevious;
174     }
175 
176     Object getContext() {
177         return _context;
178     }
179 
180     void setContext(Object context) {
181         _context = context;
182     }
183 
184     Record attachments() {
185         return _attachments;
186     }
187 
188 }