1 /*----------------------------------------------------------------------------
2 Name: XmlBlasterAccessRaw.cs
3 Project: xmlBlaster.org
4 Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file
5 Comment: Provides abstraction to xmlBlaster access from C#
6 Author: "Marcel Ruff" <xmlBlaster@marcelruff.info>
7 Date: 07/2006
8 See: http://www.xmlblaster.org/xmlBlaster/doc/requirements/interface.html
9 -----------------------------------------------------------------------------*/
10 using System;
11 using System.Text;
12 using System.Collections;
13 using System.Runtime.InteropServices;
14 //using org.xmlBlaster.util;
15
16 namespace org.xmlBlaster.client
17 {
18 public class XmlBlasterAccessFactory
19 {
20 public static I_XmlBlasterAccess CreateInstance()
21 {
22 /*
23 // Choose the PInvoke plugin:
24 # if FORCE_PINVOKECE_PLUGIN
25
26 return new PInvokeCE(); // Runs fine with WIN32 and WINCE (fails with MONO)
27
28 # elif XMLBLASTER_MONO || FORCE_NATIVEC_PLUGIN
29
30 return new NativeC(); // First try, runs fine with WIN32 and with Linux/MONO
31
32 # else // WIN32 || WINCE || Smartphone || PocketPC || WindowsCE || FORCE_PINVOKECE
33
34 return new PInvokeCE(); // Runs fine with WIN32 and WINCE (fails with MONO)
35
36 # endif*/
37 return CreateInstance("org.xmlBlaster.client.XmlBlasterAccess"); //"org.xmlBlaster.client.PInvokeCE");
38 }
39
40 /// <summary>
41 /// Create a client library instance to access xmlBlaster.
42 /// </summary>
43 /// <param name="typeName">For example "org.xmlBlaster.client.PInvokeCE", this
44 /// plugin supports Windowx CE CF2, Windows .net 2 and Linux mono 1.2</param>
45 /// <returns></returns>
46 public static I_XmlBlasterAccess CreateInstance(string typeName)
47 {
48 System.Reflection.Assembly SourceAssembly = System.Reflection.Assembly.GetExecutingAssembly();
49 return (I_XmlBlasterAccess)SourceAssembly.CreateInstance(typeName);
50 }
51 }
52
53 /// <summary>
54 /// Log levels copied from xmlBlaster client C library
55 /// See helper.h enum XMLBLASTER_LOG_LEVEL_ENUM
56 /// </summary>
57 public enum XmlBlasterLogLevel
58 {
59 /*NOLOG=0, don't use */
60 ERROR = 1, // supported, use for programming errors
61 WARN = 2, // supported, use for user errors and wrong configurations
62 INFO = 3, // supported, use for success information only
63 /*CALL=4, don't use */
64 /*TIME=5, don't use */
65 TRACE = 6, // supported, use for debugging purposes
66 DUMP = 7 // supported, use for debugging purposes
67 /*PLAIN=8 don't use */
68 }
69
70 public interface I_Callback
71 {
72 string OnUpdate(string cbSessionId, MsgUnitUpdate msgUnit);
73 }
74
75 public interface I_LoggingCallback
76 {
77 void OnLogging(XmlBlasterLogLevel logLevel, string location, string message);
78 }
79
80 public interface I_ProgressCallback
81 {
82 void OnData(bool read, int currBytesRead, int nbytes);
83 }
84
85 public enum ConnectionStateEnum
86 {
87 UNDEF = -1,
88 ALIVE = 0,
89 POLLING = 1,
90 DEAD = 2
91 }
92
93 public interface I_ConnectionStateListener
94 {
95 /**
96 * This is the callback method invoked from XmlBlasterAccess
97 * notifying the client that a connection has been established and that its status is now ALIVE.
98 *
99 * <p>
100 * Note that this method is invoked also when the connection has been
101 * established the first time. In this case the connection is fully operational
102 * but your connect() call has not yet returned. You can access the
103 * returned connect QoS in this case with <i>connect.getConnectReturnQos()</i>.
104 * </p>
105 *
106 * <p>
107 * You can erase all entries of the queue manually or add others before you return and in
108 * this way control the behavior.
109 * During you have control in <i>reachedAlive()</i> the client side
110 * queue is blocked and does not accept publish or request messages from other threads.
111 * So you can do peacefully your work (your thread is allowed to modify the queue exclusively).
112 * </p>
113 *
114 * <p>
115 * If you send messages during this method invocation they are queued only and
116 * are sent as soon as this method returns.
117 * </p>
118 *
119 * <p>
120 * This method is invoked by the login polling thread from I_XmlBlasterAccess.
121 * </p>
122 * @param oldState The previous state of the connection.
123 * @param connectionHandler An interface which allows you to control the queue and the connection
124 */
125 void reachedAlive(ConnectionStateEnum oldState, I_XmlBlasterAccess connection);
126
127 /**
128 * This is the callback method invoked from XmlBlasterAccess
129 * informing the client that the connection state has changed to POLLING.
130 *
131 * @param oldState The previous state of the connection.
132 * @param connectionHandler An interface which allows you to control the queue and the connection
133 */
134 void reachedPolling(ConnectionStateEnum oldState, I_XmlBlasterAccess connection);
135
136 /**
137 * This is the callback method invoked from XmlBlasterAccess
138 * informing the client that the connection was lost (i.e. when the state of the
139 * connection has gone to DEAD).
140 *
141 * @param oldState The previous state of the connection.
142 * @param connectionHandler An interface which allows you to control the queue and the connection
143 */
144 void reachedDead(ConnectionStateEnum oldState, I_XmlBlasterAccess connection);
145 }
146
147
148 /// <summary>
149 /// Access xmlBlaster, for details see
150 /// http://www.xmlblaster.org/xmlBlaster/doc/requirements/interface.html
151 /// All methods can throw an XmlBlasterException
152 /// </summary>
153 public interface I_XmlBlasterAccess
154 {
155 /// <summary>
156 /// Convenience to pass command line arguments
157 /// </summary>
158 /// <param name="argv">e.g. "-logLevel" "INFO"</param>
159 void Initialize(string[] argv);
160
161 /// <summary>
162 /// Initialize the client library
163 ///-dispatch/connection/pingInterval
164 /// Pinging every given milliseconds [10000]
165 /// 0 switches pinging off
166 ///-dispatch/connection/retries
167 /// How often to retry if connection fails (-1 is forever) [-1]
168 /// Set to -1 for failsafe operation
169 ///-dispatch/connection/delay
170 /// Delay between connection retries in milliseconds [5000]
171 /// </summary>
172 /// <param name="properties">e.g. "logLevel" "INFO"</param>
173 void Initialize(Hashtable properties);
174
175 /**
176 * Register a listener to get events about connection status changes.
177 * @param connectionListener null or your listener implementation on connection state changes (ALIVE | POLLING | DEAD)
178 * @see <a href="http://www.xmlBlaster.org/xmlBlaster/doc/requirements/client.failsafe.html">client.failsafe requirement</a>
179 */
180 void RegisterConnectionListener(I_ConnectionStateListener connectionListener);
181
182 ConnectReturnQos Connect(string qos, I_Callback listener);
183
184 /// After calling diconnect() this class is not usable anymore
185 /// you need to create a new instance to connect again
186 bool Disconnect(string qos);
187
188 /// <summary>
189 /// Cleanup all client side resources, the server side session
190 /// remains for a future relogin
191 /// </summary>
192 void LeaveServer();
193
194 /// <summary>
195 /// Publish a message to xmlBlaster
196 /// </summary>
197 /// <param name="msgUnit">The message to send</param>
198 /// <returns>The publish return qos</returns>
199 PublishReturnQos Publish(MsgUnit msgUnit);
200
201 /// <summary>
202 /// Convenience method to publish a message
203 /// </summary>
204 /// <param name="key">The topic description</param>
205 /// <param name="content">Your data to send</param>
206 /// <param name="qos">The required quality of service</param>
207 /// <returns>The publish return qos</returns>
208 PublishReturnQos Publish(string key, string content, string qos);
209
210 void PublishOneway(MsgUnit[] msgUnitArr);
211
212 SubscribeReturnQos Subscribe(string key, string qos);
213
214 UnSubscribeReturnQos[] UnSubscribe(string key, string qos);
215
216 EraseReturnQos[] Erase(string key, string qos);
217
218 MsgUnitGet[] Get(string key, string qos);
219
220 string Ping(string qos);
221
222 /// <summary>
223 /// Check if we have a connection to the xmlBlaster server
224 /// </summary>
225 /// <returns>true if we are connected</returns>
226 bool IsConnected();
227
228 string GetVersion();
229
230 string GetUsage();
231
232 /// <summary>
233 /// Register the given listener to receive all logging output
234 /// of the C library and C# wrapper code.
235 /// </summary>
236 /// <param name="listener">The logging is redirected to this listener</param>
237 void AddLoggingListener(I_LoggingCallback listener);
238
239 /// <summary>
240 /// Remove the given listener
241 /// </summary>
242 /// <param name="listener">Redirection is stopped for this listener</param>
243 void RemoveLoggingListener(I_LoggingCallback listener);
244
245 /// <summary>
246 /// Register the given listener to receive all logging output
247 /// of the C library and C# wrapper code.
248 /// </summary>
249 /// <param name="listener">The logging is redirected to this listener</param>
250 void AddCallbackProgressListener(I_ProgressCallback listener);
251
252 /// <summary>
253 /// Remove the given listener
254 /// </summary>
255 /// <param name="listener">Redirection is stopped for this listener</param>
256 void RemoveCallbackProgressListener(I_ProgressCallback listener);
257 /// <summary>
258 /// Returns the telephone EMEI id if available.
259 /// The International Mobile Equipment Identity (IMEI) is a 15 digit number
260 /// and unique over time and space for your PDA.
261 /// </summary>
262 /// <returns>null if not found</returns>
263 string GetEmeiId();
264
265 /// <summary>
266 /// Returns the device unique id, to be used in favour of getEmeiId().
267 /// Supported since Windows CE 5.0.1, please check
268 /// the correct behaviour on your device as it may not
269 /// be implemented properly by your vendor.
270 /// </summary>
271 /// <returns>return null if not found</returns>
272 string GetDeviceUniqueId();
273 }
274
275 public class XmlBlasterException : ApplicationException
276 {
277 // TODO: ErrorCodes
278 public static readonly string INTERNAL_ILLEGALSTATE = "internal.illegalState";
279 public static readonly string INTERNAL_UNKNOWN = "internal.unknown";
280
281 private bool remote;
282 public bool Remote
283 {
284 get { return remote; }
285 }
286 private string errorCode;
287 public string ErrorCode
288 {
289 get { return errorCode; }
290 }
291 //string message;
292 public XmlBlasterException(string errorCode, string message)
293 : base(message)
294 {
295 this.remote = false;
296 this.errorCode = errorCode;
297 }
298 public XmlBlasterException(string errorCode, string message, Exception inner)
299 : base(message, inner)
300 {
301 this.remote = false;
302 this.errorCode = errorCode;
303 }
304 public XmlBlasterException(bool remote, string errorCode, string message)
305 : base(message)
306 {
307 this.remote = remote;
308 this.errorCode = errorCode;
309 }
310 public override string ToString()
311 {
312 string ret = "errorCode=" + this.errorCode;
313 if (remote)
314 ret += " thrownFromRemote";
315 if (Message != null)
316 ret += " message=" + Message;
317 Exception inner = InnerException;
318 if (inner != null)
319 ret += inner.ToString();
320 return ret;
321 }
322 }
323
324 public class MsgUnitGet : MsgUnit
325 {
326 private GetQos getQos;
327 private GetKey getKey;
328 public MsgUnitGet(string key, byte[] content, string qos)
329 : base(key, content, qos)
330 {
331 this.getKey = new GetKey(key);
332 this.getQos = new GetQos(qos);
333 }
334
335 public GetKey GetGetKey()
336 {
337 return this.getKey;
338 }
339 public GetQos GetGetQos()
340 {
341 return this.getQos;
342 }
343 }
344
345
346 public class MsgUnitUpdate : MsgUnit
347 {
348 private UpdateQos updateQos;
349 private UpdateKey updateKey;
350 public MsgUnitUpdate(string key, byte[] content, string qos)
351 : base(key, content, qos)
352 {
353 this.updateKey = new UpdateKey(key);
354 this.updateQos = new UpdateQos(qos);
355 }
356
357 public UpdateKey GetUpdateKey()
358 {
359 return this.updateKey;
360 }
361 public UpdateQos GetUpdateQos()
362 {
363 return this.updateQos;
364 }
365 }
366
367 /// <summary>
368 /// Holds a message unit
369 /// </summary>
370 public class MsgUnit
371 {
372 protected string key;
373 protected byte[] content;
374 protected string qos;
375 protected bool oneway;
376 public MsgUnit() { }
377 public MsgUnit(string key, byte[] content, string qos)
378 {
379 this.key = key;
380 this.content = (content == null) ? new byte[0] : content;
381 this.qos = qos;
382 }
383 public MsgUnit(string key, string contentStr, string qos)
384 {
385 this.key = key;
386 SetContentStr(contentStr);
387 this.qos = qos;
388 }
389 public string GetKeyStr()
390 {
391 return this.key;
392 }
393 public string GetQosStr()
394 {
395 return this.qos;
396 }
397 public byte[] GetContent()
398 {
399 return this.content;
400 }
401 /// We return a string in the UTF-8 codeset
402 public string GetContentStr()
403 {
404 System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
405 return enc.GetString(this.content, 0, this.content.Length);
406 }
407 /// The binary string is UTF-8 encoded
408 public void SetContentStr(string contentStr)
409 {
410 System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
411 this.content = enc.GetBytes(contentStr);
412 }
413 public bool IsOneway()
414 {
415 return this.oneway;
416 }
417 public override string ToString()
418 {
419 return key + org.xmlBlaster.util.Defines.NewLine + GetContentStr() + org.xmlBlaster.util.Defines.NewLine + qos;
420 }
421 }
422 }
423
424 namespace org.xmlBlaster.util
425 {
426 public class Defines {
427 #if (WINCE || Smartphone || PocketPC || WindowsCE || CF1 || CF2)
428 public static readonly string NewLine = "\r\n";
429 #else
430 // A string containing "\r\n" for non-Unix platforms, or a string containing "\n" for Unix platforms.
431 public static readonly string NewLine = System.Environment.NewLine;
432 #endif
433 }
434 }
syntax highlighted by Code2HTML, v. 0.9.1