1 /*------------------------------------------------------------------------------
  2 Name:      SubscribeQos.java
  3 Project:   xmlBlaster.org
  4 Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file
  5 ------------------------------------------------------------------------------*/
  6 package org.xmlBlaster.client.qos;
  7 
  8 import org.xmlBlaster.util.Global;
  9 import org.xmlBlaster.util.qos.QueryQosData;
 10 import org.xmlBlaster.util.qos.ClientProperty;
 11 import org.xmlBlaster.util.qos.QuerySpecQos;
 12 import org.xmlBlaster.engine.mime.Query;
 13 import org.xmlBlaster.util.qos.AccessFilterQos;
 14 import org.xmlBlaster.util.qos.HistoryQos;
 15 import org.xmlBlaster.util.def.MethodName;
 16 
 17 /**
 18  * This class encapsulates the QoS (quality of service) of a subscribe() request. 
 19  * <p />
 20  * A full specified <b>subscribe</b> qos could look like this:<br />
 21  * <pre>
 22  *&lt;qos>
 23  *   &lt;id>__subId:/node/heron/client/joe/3/34&lt;/id> &lt; Force a subscription ID from client side -->
 24  *   &lt;meta>false&lt;/meta>       &lt;!-- Don't send me the xmlKey meta data on updates -->
 25  *   &lt;content>false&lt;/content> &lt;!-- Don't send me the content data on updates (notify only) -->
 26  *   &lt;multiSubscribe>false&lt;/multiSubscribe> &lt;!-- Ignore a second subscribe on same oid or XPATH -->
 27  *   &lt;local>false&lt;/local>     &lt;!-- Inhibit the delivery of messages to myself if i have published it -->
 28  *   &lt;initialUpdate>false&lt;/initialUpdate>;
 29  *   &lt;filter type='myPlugin' version='1.0'>a!=100&lt;/filter>
 30  *                                  &lt;!-- Filters messages i have subscribed as implemented in your plugin -->
 31  *   &lt;history numEntries='20'/>  &lt;!-- Default is to deliver the current entry (numEntries='1'), '-1' deliver all -->
 32  *&lt;/qos>
 33  * </pre>
 34  * <p />
 35  * see xmlBlaster/src/dtd/XmlQoS.xml
 36  * @see org.xmlBlaster.util.qos.QueryQosData
 37  * @see org.xmlBlaster.util.qos.QueryQosSaxFactory
 38  * @see <a href="http://www.xmlblaster.org/xmlBlaster/doc/requirements/interface.subscribe.html">subscribe interface</a>
 39  * @see <a href="http://www.xmlblaster.org/xmlBlaster/doc/requirements/mime.plugin.accessfilter.html">MIME access filter requirement</a>
 40  */
 41 public final class SubscribeQos
 42 {
 43    private final Global glob;
 44    private /*final*/ QueryQosData queryQosData;
 45 
 46    /**
 47     * Constructor for default qos (quality of service).
 48     */
 49    public SubscribeQos(Global glob) {
 50       this(glob, null);
 51    }
 52 
 53    /**
 54     * Constructor for internal use. 
 55     * @param queryQosData The struct holding the data
 56     */
 57    public SubscribeQos(Global glob, QueryQosData queryQosData) {
 58       this.glob = (glob==null) ? Global.instance() : glob;
 59       this.queryQosData = (queryQosData==null) ? new QueryQosData(this.glob, this.glob.getQueryQosFactory(), MethodName.SUBSCRIBE) : queryQosData;
 60       this.queryQosData.setMethod(MethodName.SUBSCRIBE);
 61    }
 62 
 63    /**
 64     * Access the wrapped data holder. 
 65     * @return is never null
 66     */
 67    public QueryQosData getData() {
 68       return this.queryQosData;
 69    }
 70 
 71    /**
 72     * Force the identifier (unique handle) for this subscription. 
 73     * Usually you let the identifier be generated by xmlBlaster, it is done automatically for clients with publicSessionId > 0
 74     * and multiSubscribe=false, example: '__subId:client/subscriber/session/1-exact:PublishToSlave.RUGBY_NEWS'
 75     * This is routed properly in cluster environment.
 76     * @param subId Must follow the syntax "__subId:" followed by your relative sessionName followed by a unique postfix token
 77     *  for example "__subId:client/joe/session/1-[your-unqiue-postfix]"
 78     * @see <a href="http://www.xmlBlaster.org/xmlBlaster/doc/requirements/engine.qos.subscribe.id.html">The engine.qos.subscribe.id requirement</a>
 79     * @see QueryQosData#setSubscriptionId(String)
 80     */
 81    public void setSubscriptionId(String subId) {
 82       this.queryQosData.setSubscriptionId(subId);
 83    }
 84 
 85    /**
 86     * Are multiple subscribes allowed?
 87     * Defaults to true. 
 88     * @return true Multiple subscribes deliver multiple updates
 89     *         false Ignore more than one subscribes on same oid
 90     */
 91    public void setMultiSubscribe(boolean multiSubscribe) {
 92       this.queryQosData.setMultiSubscribe(multiSubscribe);
 93    }
 94 
 95    /**
 96     * Do we want to have an initial update on subscribe if the message
 97     * exists already?
 98     * Defaults to true. 
 99     * @param initialUpdate true if initial update wanted
100     *         false if only updates on new publishes are sent
101     * @see <a href="http://www.xmlBlaster.org/xmlBlaster/doc/requirements/engine.qos.subscribe.initialUpdate.html">The engine.qos.subscribe.initialUpdate requirement</a>
102     * @see QueryQosData#setWantInitialUpdate(boolean)
103     */
104    public void setWantInitialUpdate(boolean initialUpdate) {
105       this.queryQosData.setWantInitialUpdate(initialUpdate);
106    }
107 
108    /**
109     * Do we want the callback messages of this subscription as oneway with <tt>updateOneway()</tt> or with
110     * the acknowledged <tt>update()</tt>. 
111     * @param updateOneway Defaults to false. 
112     * @see <a href="http://www.xmlBlaster.org/xmlBlaster/doc/requirements/interface.subscribe.html">The interface.subscribe requirement</a>
113     * @see QueryQosData#setWantUpdateOneway(boolean)
114     */
115    public void setWantUpdateOneway(boolean updateOneway) {
116       this.queryQosData.setWantUpdateOneway(updateOneway);
117    }
118 
119    /**
120     * false Inhibit the delivery of messages to myself if i have published it.
121     * Defaults to true. 
122     * @see QueryQosData#setWantLocal(boolean)
123     */
124    public void setWantLocal(boolean local) {
125       this.queryQosData.setWantLocal(local);
126    }
127 
128    /**
129     * If false, the update contains not the content (it is a notify of change only)
130     * <p />
131     * This may be useful if you have huge contents, and you only want to be informed about a change
132     * TODO: Implement in server!!!
133     * @see QueryQosData#setWantContent(boolean)
134     */
135    public void setWantContent(boolean content) {
136       this.queryQosData.setWantContent(content);
137    }
138 
139    /**
140     * If set to true (which is default) an erase notification message is sent
141     * to the subscriber when the topic is erased.
142     * <br />
143     * Note: For exact subscriptions this subscription gets invalid when the topic is erased
144     * and you need to subscribe again. For XPath subscriptions the subscription remains,
145     * if the same topic is created again the Xpath will match and renew the subscription.
146     * <br />
147     * The <i>state</i> in the message QoS is set to Constants.STATE_ERASED="ERASED"
148     * @param notify true - notify subscriber when the topic is erased (default is true)
149     */
150    public void setWantNotify(boolean notify) {
151       this.queryQosData.setWantNotify(notify);
152    }
153 
154    /**
155     * Adds your supplied subscribe filter. 
156     * <a href="http://www.xmlblaster.org/xmlBlaster/doc/requirements/mime.plugin.accessfilter.html">The access filter plugin requirement</a>
157     */
158    public void addAccessFilter(AccessFilterQos filter) {
159       this.queryQosData.addAccessFilter(filter);
160    }
161 
162    /**
163     * Adds your supplied get querySpec. 
164     * <a href="http://www.xmlblaster.org/xmlBlaster/doc/requirements/query.plugin.html">The query plugin requirement</a>
165     */
166    public void addQuerySpec(QuerySpecQos querySpec) {
167       this.queryQosData.addQuerySpec(querySpec);
168    }
169 
170    /**
171     * Query historical messages. 
172     */
173    public void setHistoryQos(HistoryQos historyQos) {
174       this.queryQosData.setHistoryQos(historyQos);
175    }
176 
177    /**
178     * Sets a client property (an application specific property) to the
179     * given value
180     * @param key
181     * @param value
182     */
183    public void addClientProperty(String key, Object value) {
184       this.queryQosData.addClientProperty(key, value);
185    }
186 
187    /**
188     * Read back a property. 
189     * @return The client property or null if not found
190     */
191    public ClientProperty getClientProperty(String key) {
192       return this.queryQosData.getClientProperty(key);
193    }
194 
195    /**
196     * Mark the subscription request to be persistent. 
197     * <p>
198     * Sets the persistent flag for this subscription. If this flag is
199     * set, the subscription will persist a server crash.
200     * </p>
201     * @param persistent
202     */
203    public void setPersistent(boolean persistent) {
204       this.queryQosData.setPersistent(persistent);
205    }
206 
207    /**
208     * Gets the persistent flag for this subscription. If this flag is
209     * set, the subscription will persist a server crash.
210     * @return true if persistent false otherwise.
211     */
212    public boolean getPersistent() {
213       return this.queryQosData.getPersistentProp().getValue();
214    }
215    
216    /**
217     * if __newestOnly client property is true remove older instances from callback queue of client
218     */
219    public void setNewestOnly(boolean newestOnly) {
220       this.queryQosData.setNewestOnly(newestOnly);
221    }
222 
223    /**
224     * Converts the data into a valid XML ASCII string.
225     * @return An XML ASCII string
226     */
227    public String toString() {
228       return this.queryQosData.toXml();
229    }
230 
231    /**
232     * Converts the data into a valid XML ASCII string.
233     * @return An XML ASCII string
234     */
235    public String toXml() {
236       return this.queryQosData.toXml();
237    }
238    
239    /**
240     * Returns a deep clone, you can change savely all basic or immutable types
241     * like boolean, String, int and also the ClientProperties and RouteInfo. 
242     */
243    public Object clone() throws CloneNotSupportedException {
244       SubscribeQos newOne = (SubscribeQos)super.clone();
245       if (this.queryQosData != null) {
246          newOne.queryQosData = (QueryQosData)this.queryQosData.clone();
247       }
248       return newOne;
249    }
250 
251    /** For testing: java org.xmlBlaster.client.qos.SubscribeQos */
252    public static void main(String[] args) {
253       Global glob = new Global(args);
254       try {
255          SubscribeQos qos = new SubscribeQos(glob);
256          qos.setWantContent(false);
257          qos.addAccessFilter(new AccessFilterQos(glob, "ContentLenFilter", "1.0", new Query(glob, "800")));
258          qos.addAccessFilter(new AccessFilterQos(glob, "ContentLenFilter", "3.2", new Query(glob, "a<10")));
259          System.out.println(qos.toXml());
260       }
261       catch (Throwable e) {
262          System.out.println("Test failed: " + e.toString());
263       }
264    }
265 }


syntax highlighted by Code2HTML, v. 0.9.1