1 /*------------------------------------------------------------------------------
  2 Name:      I_XmlBlasterAccess.java
  3 Project:   xmlBlaster.org
  4 Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file
  5 ------------------------------------------------------------------------------*/
  6 package org.xmlBlaster.client;
  7 
  8 import java.io.InputStream;
  9 import java.util.Map;
 10 
 11 import org.xmlBlaster.authentication.plugins.I_ClientPlugin;
 12 import org.xmlBlaster.client.key.EraseKey;
 13 import org.xmlBlaster.client.key.GetKey;
 14 import org.xmlBlaster.client.key.SubscribeKey;
 15 import org.xmlBlaster.client.key.UnSubscribeKey;
 16 import org.xmlBlaster.client.protocol.I_CallbackServer;
 17 import org.xmlBlaster.client.protocol.I_XmlBlaster;
 18 import org.xmlBlaster.client.qos.ConnectQos;
 19 import org.xmlBlaster.client.qos.ConnectReturnQos;
 20 import org.xmlBlaster.client.qos.DisconnectQos;
 21 import org.xmlBlaster.client.qos.EraseQos;
 22 import org.xmlBlaster.client.qos.EraseReturnQos;
 23 import org.xmlBlaster.client.qos.GetQos;
 24 import org.xmlBlaster.client.qos.PublishReturnQos;
 25 import org.xmlBlaster.client.qos.SubscribeQos;
 26 import org.xmlBlaster.client.qos.SubscribeReturnQos;
 27 import org.xmlBlaster.client.qos.UnSubscribeQos;
 28 import org.xmlBlaster.client.qos.UnSubscribeReturnQos;
 29 import org.xmlBlaster.util.Global;
 30 import org.xmlBlaster.util.I_ReplaceContent;
 31 import org.xmlBlaster.util.MsgUnit;
 32 import org.xmlBlaster.util.SessionName;
 33 import org.xmlBlaster.util.XmlBlasterException;
 34 import org.xmlBlaster.util.dispatch.I_PostSendListener;
 35 import org.xmlBlaster.util.error.I_MsgErrorHandler;
 36 import org.xmlBlaster.util.key.MsgKeyData;
 37 import org.xmlBlaster.util.qos.MsgQosData;
 38 import org.xmlBlaster.util.qos.address.CallbackAddress;
 39 
 40 
 41 /**
 42  * The Java client side access to xmlBlaster.
 43  * <br />
 44  * This interface hides a remote connection or a native connection to the server.
 45  * @see <a href="http://www.xmlBlaster.org/xmlBlaster/doc/requirements/interface.html">interface requirement</a>
 46  */
 47 public interface I_XmlBlasterAccess extends I_XmlBlaster, I_ConnectionHandler
 48 {
 49    /**
 50     * Register a listener to get events about connection status changes.
 51     * @param connectionListener null or your listener implementation on connection state changes (ALIVE | POLLING | DEAD)
 52     * @see <a href="http://www.xmlBlaster.org/xmlBlaster/doc/requirements/client.failsafe.html">client.failsafe requirement</a>
 53     */
 54    void registerConnectionListener(I_ConnectionStateListener connectionListener);
 55 
 56    /**
 57     * Register a listener to get notifications when a messages is successfully send from
 58     * the client side tail back queue.
 59     * Max one can be registered, any old one will be overwritten.
 60     * <p/>
 61     * A use case is that you want to get the ReturnQos when a message which was
 62     * queued on client side is finally sent to the server.
 63     * @param postSendListener The postSendListener to set, pass null to stop the listener
 64     * @return the old listener or null if no previous was registered
 65     */
 66    I_PostSendListener registerPostSendListener(I_PostSendListener postSendListener);
 67 
 68    /**
 69     * Setup the cache mode.
 70     * <p />
 71     * This installs a cache. When you call get(), a subscribe() is done
 72     * in the background that we always have a current value in our client side cache.
 73     * Further get() calls retrieve the value from the client cache.
 74     * <p />
 75     * Only the first call is used to setup the cache, following calls
 76     * are ignored silently (and return the original handle)
 77     *
 78     * @param size Size of the cache. This number specifies the count of subscriptions the cache
 79     *             can hold. It specifies NOT the number of messages.
 80     * @return The cache handle, usually of no interest
 81     * @see #getCached(GetKey, GetQos)
 82     * @see <a href="http://www.xmlBlaster.org/xmlBlaster/doc/requirements/client.cache.html">client.cache requirement</a>
 83     */
 84    public SynchronousCache createSynchronousCache(int size);
 85 
 86    /**
 87     * Use a specific error handler instead of the default one.
 88     * @param msgErrorHandler Your implementation of the error handler.
 89     * @see org.xmlBlaster.client.ClientErrorHandler
 90     */
 91    public void setClientErrorHandler(I_MsgErrorHandler msgErrorHandler);
 92 
 93    /**
 94     * Login to xmlBlaster.
 95     * <p>
 96     * Connecting with the default configuration (which checks xmlBlaster.properties and
 97     * your command line arguments):
 98     * </p>
 99     * <pre>
100     *  import org.xmlBlaster.util.Global;
101     *  ...
102     *  I_XmlBlasterAccess xmlBlasterAccess = glob.getXmlBlasterAccess();
103     *  xmlBlasterAccess.connect(null, null);
104     * </pre>
105     * <p>
106     * The default behavior is to poll automatically for the server if it is not found.
107     * As we have not specified a listener for returned messages from the server there
108     * is no callback server created.
109     * </p>
110     * <p>
111     * This example shows how to configure different behavior:
112     * </p>
113     * <pre>
114     *  // Example how to configure fail safe settings
115     *  ConnectQos connectQos = new ConnectQos(glob);
116     *
117     *  Address address = new Address(glob);
118     *  address.setDelay(4000L);      // retry connecting every 4 sec
119     *  address.setRetries(-1);       // -1 == forever
120     *  address.setPingInterval(0L);  // switched off
121     *  addr.setType("SOCKET");       // don't use CORBA protocol, but use SOCKET instead
122     *
123     *  connectQos.setAddress(address);
124     *
125     *  CallbackAddress cbAddress = new CallbackAddress(glob);
126     *  cbAddress.setDelay(4000L);      // retry connecting every 4 sec
127     *  cbAddress.setRetries(-1);       // -1 == forever
128     *  cbAddress.setPingInterval(4000L); // ping every 4 seconds
129     *  connectQos.addCallbackAddress(cbAddress);
130     *
131     *  xmlBlasterAccess.connect(connectQos, new I_Callback() {
132     *
133     *     public String update(String cbSessionId, UpdateKey updateKey, byte[] content,
134     *                          UpdateQos updateQos) {
135     *        if (updateKey.isInternal()) {
136     *           return "";
137     *        }
138     *        if (updateQos.isErased()) {
139     *           return "";
140     *        }
141     *        log.info(ME, "Receiving asynchronous message '" + updateKey.getOid() +
142     *                     "' state=" + updateQos.getState() + " in default handler");
143     *        return "";
144     *     }
145     *
146     *  });  // Login to xmlBlaster, default handler for updates;
147     * </pre>
148     * @param qos Your configuration desire
149     * @param updateListener If not null a callback server will be created and
150     *        callback messages will be routed to your updateListener.update() method.
151     * @return Can only be null if '-dispatch/connection/doSendConnect false' was set
152     * @throws XmlBlasterException only if connection state is DEAD, typically thrown on wrong configurations.
153     *            You must call connect again with different settings.
154     * @see <a href="http://www.xmlBlaster.org/xmlBlaster/doc/requirements/interface.connect.html">interface.connect requirement</a>
155     */
156    ConnectReturnQos connect(ConnectQos qos, I_Callback updateListener) throws XmlBlasterException;
157 
158    /**
159     * Create a new instance of the desired protocol driver like CORBA or RMI driver using the plugin loader.
160     * <p>
161     * Note that the returned instance is of your control only, we don't cache it in any way, this
162     * method is only a helper hiding the plugin loading.
163     * </p>
164     * @param loginName A nice name for logging purposes
165     * @param callbackAddress The callback address configuration, contains for example
166     *        type like "IOR" or "RMI" and version of the driver, e.g. "1.0"
167     * @see <a href="http://www.xmlBlaster.org/xmlBlaster/doc/requirements/protocol.html">protocol requirement</a>
168     */
169    I_CallbackServer initCbServer(String loginName, CallbackAddress callbackAddress) throws XmlBlasterException;
170 
171    /**
172     * Switch callback dispatcher on/off.
173     * This is a convenience function (see ConnectQos). It will update the client side
174     * ConnectQos as well so we don't loose the setting on reconnects after server maintenance.
175     * @param activate true: XmlBlaster server delivers callback messages
176     *        false: XmlBlaster server keeps messages for this client in the callback queue
177     */
178    void setCallbackDispatcherActive(boolean activate) throws XmlBlasterException;
179 
180    /**
181     * Convenience method to send an administrative command to xmlBlaster.
182     * If the command contains a '=' it is interpreted as a set() call, else it is used as
183     * a get() call.
184     * @param command for example "client/joe/?dispatcherActive" (a getter) or "client/joe/?dispatcherActive=false" (a setter).
185     *        The "__cmd:" is added by us
186     *        To enforce a getter or setter you can write "get client/joe/?dispatcherActive" or
187     *        "set client/joe/?dispatcherActive=false"
188     * @return When setting a value you get the returned state, else the retrieved data
189     * @throws XmlBlasterException on problems
190     */
191    String sendAdministrativeCommand(String command) throws XmlBlasterException;
192 
193    /**
194     * Access the client side security plugin.
195     * @see <a href="http://www.xmlBlaster.org/xmlBlaster/doc/requirements/security.introduction.html">security.introduction requirement</a>
196     * @see <a href="http://www.xmlBlaster.org/xmlBlaster/doc/requirements/security.development.serverPlugin.howto.html">security.development.serverPlugin.howto requirement</a>
197     */
198    I_ClientPlugin getSecurityPlugin();
199 
200    /**
201     * Logout from the server.
202     * <p />
203     * Behavior on client side:<br />
204     * Destroys pending tail back messages in the client queue
205     * and destroys low level connection and callback server.
206     * You can customize the behavior with disconnectQos.
207     * <p />
208     * Behavior on server side:<br />
209     * The server side session resources are destroyed, pending messages are deleted.
210     * <p />
211     * NOTE: If you want to keep all resources on server side for this login session
212     *       but want to halt your client,
213     *       shutdown the callback server with <code>leaveServer(null)</code>
214     *       and throw the xmlBlasterAccess instance away.
215     *       This is often the case if the client disappears and at a later point wants
216     *       to reconnect. On server side the queue for this session remains alive and
217     *       collects messages.
218     * <p />
219     * If '-dispatch/connection/doSendConnect false' was set call disconnect() nevertheless
220     * to cleanup client side resources.
221     * @param disconnectQos Describe the desired behavior on disconnect
222     * @return false if connect() wasn't called before or if you call disconnect() multiple times
223     * @see <a href="http://www.xmlBlaster.org/xmlBlaster/doc/requirements/interface.disconnect.html">interface.disconnect requirement</a>
224     */
225    boolean disconnect(DisconnectQos disconnectQos);
226 
227    /**
228     * Leaves the connection to the server and cleans up the
229     * client side resources without making a server side disconnect.
230     * This way the client side persistent messages are kept in queue while
231     * transient ones are lost. If you want to delete also the
232     * persistent messages you have to do it manually.
233     * <p>
234     * As the login session on server side stays alive, all subscriptions stay valid
235     * and callback messages are queued by the server.
236     * If you connect at a later time the server sends us all queued messages.
237     * </p>
238     * <p>
239     * Once you have called this method the I_XmlBlasterAccess
240     * becomes invalid and any further invocation results in
241     * an XmlBlasterException to be thrown.
242     * </p>
243     *
244     * @param map The properties to pass while leaving server.
245     *        Currently this argument has no effect. You can
246     *        pass null as a parameter.
247     */
248    void leaveServer(Map map);
249 
250    /**
251     * Has the connect() method successfully passed?
252     * <p>
253     * Note that this contains no information about the current connection state
254     * of the protocol layer.
255     * </p>
256     * @return true If the connection() method was invoked without exception
257     * @see I_ConnectionHandler#isAlive()
258     * @see I_ConnectionHandler#isPolling()
259     * @see I_ConnectionHandler#isDead()
260     */
261    boolean isConnected();
262 
263    /**
264     * Send an event to xmlBlaster to refresh the login session life time.
265     * @see <a href="http://www.xmlblaster.org/xmlBlaster/doc/requirements/engine.qos.login.session.html">session requirement</a>
266     * @throws XmlBlasterException like ErrorCode.USER_NOT_CONNECTED and others
267     */
268    void refreshSession() throws XmlBlasterException;
269 
270    /**
271     * Access the returned QoS of a connect() call.
272     * @return is null if connect() was not called before
273     */
274    ConnectReturnQos getConnectReturnQos();
275 
276    /**
277     * Access the current ConnectQos.
278     * @return is null if connect() was not called before
279     */
280    ConnectQos getConnectQos();
281 
282    /**
283     * Access the callback server which is currently used in I_XmlBlasterAccess.
284     * The callback server is not null if you have passes a I_Callback handle on connect().
285     * @return null if no callback server is established
286     * @see <a href="http://www.xmlBlaster.org/xmlBlaster/doc/requirements/protocol.html">protocol requirement</a>
287     * @see #connect(ConnectQos, I_Callback)
288     */
289    I_CallbackServer getCbServer();
290 
291    /**
292     * A unique name for this client, for logging only
293     * @return e.g. "/node/heron/client/joe/3"
294     */
295    String getId();
296 
297    /**
298     * The public session ID of this login session.
299     * This is a convenience method only, the information is from ConnectReturnQos or if not available
300     * from ConnectQos.
301     * @return null if not known
302     * @see <a href="http://www.xmlBlaster.org/xmlBlaster/doc/requirements/client.failsafe.html">client.failsafe requirement</a>
303     */
304    SessionName getSessionName();
305 
306    String getStorageIdStr();
307 
308    /**
309     * Allows to set a unique client side queue name (connection queue).
310     * Useful only if you code connects to multiple servers with the same login name.
311     * Use with very caution to be unique in complete database!
312     * @param prefix For example "toserver1"+sessionName.getRelativeName()
313     */
314    void setStorageIdStr(String prefix);
315 
316    /**
317     * Allows to set the node name for nicer logging.
318     * Used for clustering.
319     * @param nodeId For example "/xmlBlaster/node/heron"
320     */
321    void setServerNodeId(String nodeId);
322 
323    /**
324     * The cluster node id (name) to which we want to connect.
325     * <p />
326     * Needed for creating the unique queue / DB-store name. Is essential if same
327     * client loginName and session is used to connect to more the one server.
328     * <p />
329     * Needed additionally for nicer logging when running in a cluster.<br />
330     * Is configurable with "-server.node.id golan"
331     * 
332     * @return e.g. "golan", defaults to "xmlBlaster"
333     */
334    String getServerNodeId();
335 
336    //SubscribeReturnQos subscribe(java.lang.String xmlKey, java.lang.String qos) throws XmlBlasterException;
337    /**
338     * Subscribe to messages.
339     * <p>
340     * The messages are delivered asynchronous with the update() method.
341     * </p>
342     * @param subscribeKey Which message topics to retrieve
343     * @param subscribeQos Control the behavior and further filter messages with mime based filter plugins
344     * @return Is never null
345     * @see org.xmlBlaster.client.I_Callback#update(String, org.xmlBlaster.client.key.UpdateKey, byte[], org.xmlBlaster.client.qos.UpdateQos)
346     * @see <a href="http://www.xmlBlaster.org/xmlBlaster/doc/requirements/interface.subscribe.html">interface.subscribe requirement</a>
347     * @throws XmlBlasterException like ErrorCode.USER_NOT_CONNECTED and others
348     */
349    SubscribeReturnQos subscribe(SubscribeKey subscribeKey, SubscribeQos subscribeQos) throws XmlBlasterException;
350 
351    /**
352     * This subscribe variant allows to specify a specialized callback
353     * for updated messages.
354     * <p />
355     * This way you can implement for every subscription a specific callback,
356     * so you don't need to dispatch updates when they are received in only one central
357     * update method.
358     * <p />
359     * Example:<br />
360     * <pre>
361     *   XmlBlasterAccess con = ...   // login etc.
362     *   ...
363     *   SubscribeKey key = new SubscribeKey(glob, "//stock", "XPATH");
364     *   SubscribeQos qos = new SubscribeQos(glob);
365     *   try {
366     *      con.subscribe(key, qos, new I_Callback() {
367     *            public String update(String name, UpdateKey updateKey, byte[] content, UpdateQos updateQos) {
368     *               System.out.println("Receiving message for '//stock' subscription ...");
369     *               return "";
370     *            }
371     *         });
372     *   } catch(XmlBlasterException e) {
373     *      System.out.println(e.getMessage());
374     *   }
375     * </pre>
376     * <p />
377     * NOTE: You need to pass a callback handle on login as well (even if you
378     * never use it). It allows to setup the callback server and is the
379     * default callback deliver channel for PtP messages.
380     * <p />
381     * NOTE: On logout we automatically unSubscribe() this subscription
382     * if not done before.
383     * @param cb      Your callback handling implementation
384     * @return SubscribeReturnQos with the unique subscriptionId<br>
385     *                If you subscribed using a query, the subscription ID of this<br>
386     *                query handling object (SubscriptionInfo.getUniqueKey()) is returned.<br>
387     *                You should use this ID if you wish to unSubscribe()
388     *         Is never null
389     * @see <a href="http://www.xmlBlaster.org/xmlBlaster/doc/requirements/interface.subscribe.html">interface.subscribe requirement</a>
390     * @throws XmlBlasterException like ErrorCode.USER_NOT_CONNECTED and others
391     */
392    SubscribeReturnQos subscribe(SubscribeKey subscribeKey, SubscribeQos subscribeQos, I_Callback cb) throws XmlBlasterException;
393 
394    /**
395     * Subscribe to messages.
396     * @param xmlKey Which message topics to retrieve
397     * @param xmlQos Control the behavior and further filter messages with mime based filter plugins
398     * @return is never null
399     * @see I_XmlBlasterAccess#subscribe(SubscribeKey, SubscribeQos, I_Callback)
400     * @throws XmlBlasterException like ErrorCode.USER_NOT_CONNECTED and others
401     */
402    SubscribeReturnQos subscribe(String xmlKey, String xmlQos, I_Callback cb) throws XmlBlasterException;
403 
404    /**
405     * Access synchronously messages. They are on first request subscribed
406     * and cached on client side.
407     * <p>
408     * A typical use case is a servlet which receives many HTML requests and
409     * usually the message has not changed. This way we avoid asking xmlBlaster
410     * every time for the information but take it directly from the cache.
411     * </p>
412     * <p>
413     * The cache is always up to date as it has subscribed on this topic
414     * </p>
415     * <p>
416     * You need to call <i>createSynchronousCache()</i> before using <i>getCached()</i>.
417     * </p>
418     * <p>
419     * NOTE: Passing two similar getKey but with different getQos filters is currently not supported.
420     * </p>
421     * <p>
422     * NOTE: GetKey requests with EXACT oid are automatically removed from cache when
423     *       the topic with this oid is erased. XPATH queries are removed from cache
424     *       when the last topic oid which matched the XPATH disappears.
425     * </p>
426     * @param getKey Which message topics to retrieve
427     * @param getQos Control the behavior and further filter messages with mime based filter plugins
428     * @return An array of messages, the sequence is arbitrary, never null
429     * @throws XmlBlasterException if <i>createSynchronousCache()</i> was not used to establish a cache first
430     * @see #createSynchronousCache(int)
431     * @see <a href="http://www.xmlBlaster.org/xmlBlaster/doc/requirements/client.cache.html">client.cache requirement</a>
432     * @throws XmlBlasterException like ErrorCode.USER_NOT_CONNECTED and others
433     */
434    public MsgUnit[] getCached(GetKey getKey, GetQos getQos) throws XmlBlasterException;
435 
436    //MsgUnit[] get(java.lang.String xmlKey, java.lang.String qos) throws XmlBlasterException;
437    /**
438     * Get synchronous messages.
439     * @param getKey Which message topics to retrieve
440     * @param getQos Control the behavior and further filter messages with mime based filter plugins
441     * @return never null
442     * @see <a href="http://www.xmlBlaster.org/xmlBlaster/doc/requirements/interface.get.html">interface.get requirement</a>
443     * @throws XmlBlasterException like ErrorCode.USER_NOT_CONNECTED and others
444     */
445    MsgUnit[] get(GetKey getKey, GetQos getQos) throws XmlBlasterException;
446 
447    // @param maxBytes The total size of all returned messages together must not exceed this value.
448    //       This is not implemented yet since the size of the entries in the queue is not guaranteed
449    //       to be related to the size of the MsgUnits
450    //RELATING_CALLBACK = "callback";
451    //RELATING_SUBJECT = "subject";
452    //RELATING_HISTORY = "history";
453    /**
454     * This method synchronously accesses maxEntries messages from any xmlBlaster server side queue.
455     * <p>
456     * This is a convenience method which uses get() with a specific Qos.
457     * <p>Important note:<br />
458     * Currently you shouldn't use unlimited timeout==-1 as this could
459     * lead to a server side thread leak on client disconnect.
460     * As a workaround please use a loop and a timeout of for example 60000
461     * and just ignore returned arrays of length 0.
462     * </p>
463     * @param oid The identifier like
464     *            "topic/hello" to access a history queue,
465     *            "client/joe" to access a subject queue or
466     *            "client/joe/session/1"
467     *            to access a callback queue.
468     *            The string must follow the formatting rule of ContextNode.java
469     * @param maxEntries The maximum number of entries to retrieve
470     * @param timeout The time to wait until return.
471     *                If you choose a negative value it will block until the maxEntries
472     *                has been reached.
473     *                If the value is '0' (i.e. zero) it will not wait and will correspond to a non-blocking get.
474     *                If the value is positive it will block until the specified amount in milliseconds
475     *                has elapsed or when the maxEntries has been reached (whichever comes first).
476     * @param consumable  Expressed with 'true' or 'false'.
477     *                    If true the entries returned are deleted from the queue
478     * @return An array of messages, is never null but may be an array of length=0 if no message is delivered
479     * @see org.xmlBlaster.util.context.ContextNode
480     * @see <a href="http://www.xmlblaster.org/xmlBlaster/doc/requirements/engine.qos.queryspec.QueueQuery.html">engine.qos.queryspec.QueueQuery requirement</a>
481     * @see javax.jms.MessageConsumer#receive
482     */
483    MsgUnit[] receive(String oid, int maxEntries, long timeout, boolean consumable) throws XmlBlasterException;
484 
485 
486    //UnSubscribeReturnQos[] unSubscribe(java.lang.String xmlKey, java.lang.String qos) throws XmlBlasterException;
487    /**
488     * Cancel subscription.
489     * @param unSubscribeKey Which messages to cancel
490     * @param unSubscribeQos Control the behavior
491     * @return The status of the unSubscribe request, is never null
492     * @see <a href="http://www.xmlBlaster.org/xmlBlaster/doc/requirements/interface.unSubscribe.html">interface.unSubscribe requirement</a>
493     * @throws XmlBlasterException like ErrorCode.USER_NOT_CONNECTED and others
494     */
495    UnSubscribeReturnQos[] unSubscribe(UnSubscribeKey unSubscribeKey, UnSubscribeQos unSubscribeQos) throws XmlBlasterException;
496 
497    /**
498     * @see <a href="http://www.xmlBlaster.org/xmlBlaster/doc/requirements/interface.publish.html">interface.publish requirement</a>
499     */
500    PublishReturnQos publish(MsgUnit msgUnit) throws XmlBlasterException;
501    //Rename publishArr() to publish
502    //PublishReturnQos[] publish(org.xmlBlaster.util.MsgUnit[] msgUnitArr) throws XmlBlasterException;
503    /**
504     * Publish messages.
505     * @param msgUnitArr The messages to send to the server
506     * @see <a href="http://www.xmlBlaster.org/xmlBlaster/doc/requirements/interface.publish.html">interface.publish requirement</a>
507     * @throws XmlBlasterException like ErrorCode.USER_NOT_CONNECTED and others
508     */
509    void publishOneway(org.xmlBlaster.util.MsgUnit [] msgUnitArr) throws XmlBlasterException;
510 
511    /**
512     * Publishes one message in streaming manner, if the message content is too big to fit in one single chunk, the message
513     * is split in several smaller messages (called chunks) and these are published. During the publishing of these messages,
514     * the method blocks.
515     * 
516     * @param is The input stream from which to read the input data.
517     * @param keyData The key for the message (same for all chunks)
518     * @param qosData The qos for all messages (same for all chunks besides internal stuff added in this method)
519     * @param maxBufSize The maximum content size of each chunk.
520     * @param contentReplacer an optional content replacer (i.e. a modifier of the content) can be null.
521     * @return an array containing the return qos. Currently an array of length 1 is returned containing the return qos for
522     * the first message.
523     * @throws XmlBlasterException
524     */
525    PublishReturnQos[] publishStream(InputStream is, MsgKeyData keyData, MsgQosData qosData, int maxBufSize, I_ReplaceContent contentReplacer) throws XmlBlasterException;
526 
527    /**
528     * Implements the blocking request/reply pattern.
529     * <p>
530     * The msgUnit should contain a PublishQos which routes the request
531     * to the desired client, for example sending it to client <code>joe</code>
532     * and its login session <code>1</code> or sending it to a topic which was subscribed
533     * by the destination client:
534     * <pre>
535     * import org.xmlBlaster.util.qos.address.Destination;
536     * import org.xmlBlaster.client.qos.PublishQos;
537     *  ...
538     *  Global glob = ...;
539     *  ...
540     *  PublishQos pq = new PublishQos(glob);
541     *  Destination dest = new Destination(glob, new SessionName(glob, "joe/1"));
542     *  dest.forceQueuing(true);
543     *  pq.addDestination(dest);
544     *  </pre>
545     *  <p>
546     *  This receiver needs to send the response to the topic oid as passed with
547     *  the client property "__jms:JMSReplyTo":
548     *  <pre>
549     *  String tempTopicOid = updateQos.getClientProperty(Constants.JMS_REPLY_TO, "");
550     *  // Send reply back ...
551     *  PublishKey pk = new PublishKey(glob, tempTopicOid);
552     *  ...
553     *  </pre>
554     *
555     *  <p>
556     *  This approach is similar to the JMS approach for request/reply (TopicRequestor.java)
557     *  but we have the choice to send the msgUnit directly to another client or to a topic (as JMS),
558     *  and we can handle multiple replies for one request.
559     *  <p>
560     *  The feature is implemented on client side with a temporary response topic and a <code>receive()</code> call.
561     *  The temporary response topic is erased after the response has arrived.
562     *  <br />
563     *  You can optionally add a clientProperty "__responseTopicIdPrefix", this topicId is
564     *  used as a prefix for the temporary response topicId. the given prefix must be unique
565     *  between clients. This is thread safe.
566     *  A use case could be to simplify detecting the topic for an authorizer plugin.
567     *  <br />
568     *  You can optionally add a clientProperty "__responseTopicId" with a unique topicId
569     *  to avoid the creation of temporary response topics, note that this feature
570     *  is NOT thread safe, the client may only send one request() at a time.
571     *  The response topic will live for one day after last usage.
572     *  A reason to do so could be the better performance (avoid short living temporary response topics).
573     *  <p>
574     *  Please note the timeout limitation as described at
575     *  {@link #receive(String, int, long, boolean)})
576     *
577     * @param msgUnit The request to send. The topicId may be any you wish for the receiver to recognize.
578     *        If the receiver has not subsribed on this topicId you need to send it PtP (add the Destination client).
579     * @param timeout The milliseconds to block, 0 is none blocking, -1 blocks forever
580     * @param maxEntries The maximum number of entries to deliver or return with less after timeout
581     * @return The response messages, typically one, never null, has 0 entries on timeout
582     * @see <a href="http://www.xmlBlaster.org/xmlBlaster/demo/HelloWorld8.java.html">HelloWorld8.java</a>
583     */
584    MsgUnit[] request(MsgUnit msgUnit, long timeout, int maxEntries) throws XmlBlasterException;
585 
586    //EraseReturnQos[] erase(java.lang.String xmlKey, java.lang.String qos) throws XmlBlasterException;
587    /**
588     * @param eraseKey The topics to erase
589     * @param eraseQos Control the erase behavior
590     * @return The status of the erase request, is never null
591     * @see <a href="http://www.xmlBlaster.org/xmlBlaster/doc/requirements/interface.erase.html">interface.erase requirement</a>
592     * @throws XmlBlasterException like ErrorCode.USER_NOT_CONNECTED and others
593     */
594    EraseReturnQos[] erase(EraseKey eraseKey, EraseQos eraseQos) throws XmlBlasterException;
595 
596    /**
597     * Force a async ping to re-check connection to server. Status change can be
598     * got asynchronously via registerConnectionListener()
599     */
600    public void ping();
601 
602    /**
603     * Access the environment settings of this connection.
604     * <p>
605     * Enforced by interface I_ConnectionHandler
606     * </p>
607     * 
608     * @return The global handle (like a stack with local variables for this
609     *         connection)
610     */
611    Global getGlobal();
612 
613    /**
614     * Dump state of this client connection handler into an XML ASCII string.
615     * @return internal state
616     */
617    String toXml();
618 
619    /**
620     * Can be freely used by client code to store an object and later retrieve
621     * it.
622     * 
623     * @return the object from setUserObject or null
624     */
625    public Object getUserObject();
626 
627    /**
628     * Can be freely used by client code to store an object and later retrieve
629     * it.
630     * 
631     * @param userObject
632     *           any user object
633     */
634    public void setUserObject(Object userObject);
635 }


syntax highlighted by Code2HTML, v. 0.9.1