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 }