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 *<qos>
23 * <id>__subId:/node/heron/client/joe/3/34</id> < Force a subscription ID from client side -->
24 * <meta>false</meta> <!-- Don't send me the xmlKey meta data on updates -->
25 * <content>false</content> <!-- Don't send me the content data on updates (notify only) -->
26 * <multiSubscribe>false</multiSubscribe> <!-- Ignore a second subscribe on same oid or XPATH -->
27 * <local>false</local> <!-- Inhibit the delivery of messages to myself if i have published it -->
28 * <initialUpdate>false</initialUpdate>;
29 * <filter type='myPlugin' version='1.0'>a!=100</filter>
30 * <!-- Filters messages i have subscribed as implemented in your plugin -->
31 * <history numEntries='20'/> <!-- Default is to deliver the current entry (numEntries='1'), '-1' deliver all -->
32 *</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