1 package org.opentrafficsim.imb.transceiver;
2
3 import java.rmi.RemoteException;
4 import java.util.HashMap;
5 import java.util.Map;
6
7 import org.opentrafficsim.core.dsol.OTSDEVSSimulatorInterface;
8 import org.opentrafficsim.imb.IMBException;
9 import org.opentrafficsim.imb.connector.Connector;
10
11 import nl.tno.imb.TByteBuffer;
12 import nl.tudelft.simulation.event.EventInterface;
13 import nl.tudelft.simulation.event.EventProducer;
14 import nl.tudelft.simulation.event.EventProducerInterface;
15 import nl.tudelft.simulation.event.EventType;
16 import nl.tudelft.simulation.language.Throw;
17
18
19
20
21
22
23
24
25
26
27
28
29 public abstract class AbstractTransceiver extends EventProducer implements EventTransceiver
30 {
31
32 private static final long serialVersionUID = 20160909L;
33
34
35 private final String id;
36
37
38 private final Connector connector;
39
40
41 private final OTSDEVSSimulatorInterface simulator;
42
43
44 private Map<String, IMBMessageHandler> imbMessageHandlerMap = new HashMap<>();
45
46
47 private Map<EventType, String> otsToIMBMap = new HashMap<>();
48
49
50 private Map<EventType, OTSToIMBTransformer> otsTransformerMap = new HashMap<>();
51
52
53
54
55
56
57
58
59 public AbstractTransceiver(final String id, final Connector connector, final OTSDEVSSimulatorInterface simulator)
60 {
61 Throw.whenNull(connector, "Connector can not be null");
62 Throw.whenNull(id, "id can not be null");
63 Throw.whenNull(simulator, "simulator can not be null");
64 this.id = id;
65 this.connector = connector;
66 this.simulator = simulator;
67 }
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84 public final void addOTSToIMBChannel(final EventProducerInterface producer, final EventType eventType,
85 final String imbEventName, Object[] imbNewPayload, final OTSToIMBTransformer transformer) throws IMBException
86 {
87 Throw.whenNull(producer, "producer cannot be null");
88 Throw.whenNull(eventType, "eventType cannot be null");
89 Throw.whenNull(imbEventName, "imbEventName cannot be null");
90 Throw.whenNull(imbNewPayload, "imbNewPayload cannot be null");
91 Throw.whenNull(transformer, "transformer cannot be null");
92 Throw.when(this.otsToIMBMap.containsKey(eventType) && !this.otsToIMBMap.get(eventType).equals(imbEventName),
93 IMBException.class, "mapping of EventType to IMB name cannot be changed");
94 Throw.when(this.otsTransformerMap.containsKey(eventType) && !this.otsTransformerMap.get(eventType).equals(transformer),
95 IMBException.class, "mapping of EventType to Transformer cannot be changed");
96
97 try
98 {
99 this.connector.postIMBMessage(imbEventName, Connector.IMBEventType.NEW, imbNewPayload);
100 this.otsToIMBMap.put(eventType, imbEventName);
101 this.otsTransformerMap.put(eventType, transformer);
102 producer.addListener(this, eventType);
103 }
104 catch (RemoteException exception)
105 {
106 throw new IMBException(exception);
107 }
108 }
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123 public final void removeOTSToIMBChannel(final EventProducerInterface producer, final EventType eventType,
124 Object[] imbDeletePayload) throws IMBException
125 {
126 Throw.whenNull(producer, "producer cannot be null");
127 Throw.whenNull(eventType, "eventType cannot be null");
128 Throw.whenNull(imbDeletePayload, "imbDeletePayload cannot be null");
129 Throw.when(!this.otsToIMBMap.containsKey(eventType), IMBException.class, "EventType " + eventType
130 + " for this channel was not registered with an addOTSToIMBChannel call");
131
132 try
133 {
134 producer.removeListener(this, eventType);
135 this.connector.postIMBMessage(this.otsToIMBMap.get(eventType), Connector.IMBEventType.DELETE, imbDeletePayload);
136
137 }
138 catch (Exception exception)
139 {
140 throw new IMBException(exception);
141 }
142 }
143
144
145 @Override
146 public void notify(final EventInterface event) throws RemoteException
147 {
148 String imbEventName = this.otsToIMBMap.get(event.getType());
149 if (null != imbEventName)
150 {
151
152
153
154
155 try
156 {
157 this.connector.postIMBMessage(imbEventName, Connector.IMBEventType.CHANGE,
158 this.otsTransformerMap.get(event.getType()).transform(event));
159 }
160 catch (Exception exception)
161 {
162 exception.printStackTrace();
163 }
164 }
165 }
166
167
168
169
170
171
172
173
174
175
176
177 public void addIMBtoOTSChannel(final String imbEventName, final EventType eventType,
178 final IMBToOTSTransformer imbToOTSTransformer) throws IMBException
179 {
180 Throw.whenNull(imbEventName, "imbEventName cannot be null");
181 Throw.whenNull(eventType, "eventType cannot be null");
182 Throw.whenNull(imbToOTSTransformer, "imbToOTSTransformer cannot be null");
183
184 this.imbMessageHandlerMap.put(imbEventName, new PubSubIMBMessageHandler(imbEventName, eventType, imbToOTSTransformer,
185 this.simulator));
186 this.connector.register(imbEventName, this);
187 }
188
189
190
191
192
193
194
195 public void addIMBtoOTSChannel(final String imbEventName, final IMBMessageHandler imbMessageHandler) throws IMBException
196 {
197 Throw.whenNull(imbEventName, "imbEventName cannot be null");
198 Throw.whenNull(imbMessageHandler, "imbMessageHandler cannot be null");
199
200 this.imbMessageHandlerMap.put(imbEventName, imbMessageHandler);
201 this.connector.register(imbEventName, this);
202 }
203
204
205 @Override
206 public void handleMessageFromIMB(final String imbEventName, final TByteBuffer imbPayload) throws IMBException
207 {
208 Throw.when(!this.imbMessageHandlerMap.containsKey(imbEventName), IMBException.class,
209 "Could not find IMB-to-OTS handler for IMB event name " + imbEventName);
210 this.imbMessageHandlerMap.get(imbEventName).handle(imbPayload);
211 }
212
213
214 @Override
215 public String getId()
216 {
217 return this.id;
218 }
219
220
221 @Override
222 public final Connector getConnector()
223 {
224 return this.connector;
225 }
226
227
228 @Override
229 @SuppressWarnings("checkstyle:designforextension")
230 public String toString()
231 {
232 return "AbstractTransceiver [id=" + this.id + ", connector=" + this.connector + "]";
233 }
234
235
236
237
238
239 public OTSDEVSSimulatorInterface getSimulator()
240 {
241 return this.simulator;
242 }
243
244 }