1 /*----------------------------------------------------------------------------
  2 Name:      XmlBlasterAccess.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