/*------------------------------------------------------------------------------ Name: SubscribeQos.java Project: xmlBlaster.org Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file ------------------------------------------------------------------------------*/ package org.xmlBlaster.client.qos; import org.xmlBlaster.util.Global; import org.xmlBlaster.util.qos.QueryQosData; import org.xmlBlaster.util.qos.ClientProperty; import org.xmlBlaster.util.qos.QuerySpecQos; import org.xmlBlaster.engine.mime.Query; import org.xmlBlaster.util.qos.AccessFilterQos; import org.xmlBlaster.util.qos.HistoryQos; import org.xmlBlaster.util.def.MethodName; /** * This class encapsulates the QoS (quality of service) of a subscribe() request. *
* A full specified subscribe qos could look like this:*<qos> * <id>__subId:/node/heron/client/joe/3/34</id> < Force a subscription ID from client side --> * <meta>false</meta> <!-- Don't send me the xmlKey meta data on updates --> * <content>false</content> <!-- Don't send me the content data on updates (notify only) --> * <multiSubscribe>false</multiSubscribe> <!-- Ignore a second subscribe on same oid or XPATH --> * <local>false</local> <!-- Inhibit the delivery of messages to myself if i have published it --> * <initialUpdate>false</initialUpdate>; * <filter type='myPlugin' version='1.0'>a!=100</filter> * <!-- Filters messages i have subscribed as implemented in your plugin --> * <history numEntries='20'/> <!-- Default is to deliver the current entry (numEntries='1'), '-1' deliver all --> *</qos> ** * see xmlBlaster/src/dtd/XmlQoS.xml * @see org.xmlBlaster.util.qos.QueryQosData * @see org.xmlBlaster.util.qos.QueryQosSaxFactory * @see subscribe interface * @see MIME access filter requirement */ public final class SubscribeQos { private final Global glob; private /*final*/ QueryQosData queryQosData; /** * A subscribe can add such clientProperties, eg "_bounce:oid" = "100" * and the SubscribeReturnQos will return the stripped clientProperty key "oid" and its value "100" */ public static final String KEY_BOUNCE_CP = "_bounce:"; /** * Constructor for default qos (quality of service). */ public SubscribeQos(Global glob) { this(glob, null); } /** * Constructor for internal use. * @param queryQosData The struct holding the data */ public SubscribeQos(Global glob, QueryQosData queryQosData) { this.glob = (glob==null) ? Global.instance() : glob; this.queryQosData = (queryQosData==null) ? new QueryQosData(this.glob, this.glob.getQueryQosFactory(), MethodName.SUBSCRIBE) : queryQosData; this.queryQosData.setMethod(MethodName.SUBSCRIBE); } /** * Access the wrapped data holder. * @return is never null */ public QueryQosData getData() { return this.queryQosData; } /** * Force the identifier (unique handle) for this subscription. * Usually you let the identifier be generated by xmlBlaster, it is done automatically for clients with publicSessionId > 0 * and multiSubscribe=false, example: '__subId:client/subscriber/session/1-exact:PublishToSlave.RUGBY_NEWS' * This is routed properly in cluster environment. * @param subId Must follow the syntax "__subId:" followed by your relative sessionName followed by a unique postfix token * for example "__subId:client/joe/session/1-[your-unqiue-postfix]" * @see The engine.qos.subscribe.id requirement * @see QueryQosData#setSubscriptionId(String) */ public void setSubscriptionId(String subId) { this.queryQosData.setSubscriptionId(subId); } /** * Are multiple subscribes allowed? * Defaults to true. * @return true Multiple subscribes deliver multiple updates * false Ignore more than one subscribes on same oid */ public void setMultiSubscribe(boolean multiSubscribe) { this.queryQosData.setMultiSubscribe(multiSubscribe); } /** * Do we want to have an initial update on subscribe if the message * exists already? * Defaults to true. * @param initialUpdate true if initial update wanted * false if only updates on new publishes are sent * @see The engine.qos.subscribe.initialUpdate requirement * @see QueryQosData#setWantInitialUpdate(boolean) */ public void setWantInitialUpdate(boolean initialUpdate) { this.queryQosData.setWantInitialUpdate(initialUpdate); } /** * Do we want the callback messages of this subscription as oneway with updateOneway() or with * the acknowledged update(). * @param updateOneway Defaults to false. * @see The interface.subscribe requirement * @see QueryQosData#setWantUpdateOneway(boolean) */ public void setWantUpdateOneway(boolean updateOneway) { this.queryQosData.setWantUpdateOneway(updateOneway); } /** * false Inhibit the delivery of messages to myself if i have published it. * Defaults to true. * @see QueryQosData#setWantLocal(boolean) */ public void setWantLocal(boolean local) { this.queryQosData.setWantLocal(local); } /** * If false, the update contains not the content (it is a notify of change only) * * This may be useful if you have huge contents, and you only want to be informed about a change * TODO: Implement in server!!! * @see QueryQosData#setWantContent(boolean) */ public void setWantContent(boolean content) { this.queryQosData.setWantContent(content); } /** * If set to true (which is default) an erase notification message is sent * to the subscriber when the topic is erased. *
* Sets the persistent flag for this subscription. If this flag is * set, the subscription will persist a server crash. *
* @param persistent */ public void setPersistent(boolean persistent) { this.queryQosData.setPersistent(persistent); } /** * Gets the persistent flag for this subscription. If this flag is * set, the subscription will persist a server crash. * @return true if persistent false otherwise. */ public boolean getPersistent() { return this.queryQosData.getPersistentProp().getValue(); } /** * if __newestOnly client property is true remove older instances from callback queue of client */ public void setNewestOnly(boolean newestOnly) { this.queryQosData.setNewestOnly(newestOnly); } /** * Converts the data into a valid XML ASCII string. * @return An XML ASCII string */ public String toString() { return this.queryQosData.toXml(); } /** * Converts the data into a valid XML ASCII string. * @return An XML ASCII string */ public String toXml() { return this.queryQosData.toXml(); } /** * Returns a deep clone, you can change savely all basic or immutable types * like boolean, String, int and also the ClientProperties and RouteInfo. */ public Object clone() throws CloneNotSupportedException { SubscribeQos newOne = (SubscribeQos)super.clone(); if (this.queryQosData != null) { newOne.queryQosData = (QueryQosData)this.queryQosData.clone(); } return newOne; } /** For testing: java org.xmlBlaster.client.qos.SubscribeQos */ public static void main(String[] args) { Global glob = new Global(args); try { SubscribeQos qos = new SubscribeQos(glob); qos.setWantContent(false); qos.addAccessFilter(new AccessFilterQos(glob, "ContentLenFilter", "1.0", new Query(glob, "800"))); qos.addAccessFilter(new AccessFilterQos(glob, "ContentLenFilter", "3.2", new Query(glob, "a<10"))); System.out.println(qos.toXml()); } catch (Throwable e) { System.out.println("Test failed: " + e.toString()); } } }