1 /*------------------------------------------------------------------------------
2 Name: PublishQos.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.XmlBlasterException;
10 import org.xmlBlaster.util.SessionName;
11 import org.xmlBlaster.util.def.Constants;
12 import org.xmlBlaster.util.def.PriorityEnum;
13 import org.xmlBlaster.util.qos.MsgQosData;
14 import org.xmlBlaster.util.qos.ClientProperty;
15 import org.xmlBlaster.util.qos.address.Destination;
16 import org.xmlBlaster.util.qos.TopicProperty;
17 import org.xmlBlaster.util.def.MethodName;
18
19
20 /**
21 * This class encapsulates the qos of a publish() message.
22 * <p />
23 * So you don't need to type the 'ugly' XML ASCII string by yourself.
24 * After construction access the ASCII-XML string with the toXml() method.
25 * <br />
26 * A typical <b>publish</b> qos in Publish/Subcribe mode could look like this:<br />
27 * <pre>
28 * <qos>
29 * <priority>5</priority>
30 * <expiration lifeTime='60000' forceDestroy='false'/>
31 * <persistent /> <!-- The message shall be recoverable if xmlBlaster crashes -->
32 * <forceUpdate>true</forceUpdate>
33 * <readonly />
34 * </qos>
35 * </pre>
36 * A typical <b>publish</b> qos in PtP mode could look like this:<br />
37 * <pre>
38 * <qos>
39 * <destination queryType='EXACT' forceQueuing='true'>
40 * joe
41 * </destination>
42 * <destination>
43 * /node/heron/client/Tim/-2
44 * </destination>
45 * </qos>
46 * </pre>
47 * <p />
48 * see xmlBlaster/src/dtd/XmlQoS.xml
49 * @see org.xmlBlaster.util.qos.MsgQosSaxFactory
50 * @see <a href="http://www.xmlblaster.org/xmlBlaster/doc/requirements/interface.publish.html">publish interface</a>
51 */
52 public final class PublishQos
53 {
54 private final Global glob;
55 private final MsgQosData msgQosData;
56
57 public PublishQos(Global glob, String serialData) {
58 this.glob = (glob==null) ? Global.instance() : glob;
59 this.msgQosData = new MsgQosData(this.glob, this.glob.getMsgQosFactory(), serialData, MethodName.PUBLISH);
60 this.msgQosData.setMethod(MethodName.PUBLISH);
61 }
62
63 /**
64 * Default constructor for transient messages.
65 */
66 public PublishQos(Global glob) {
67 this.glob = (glob==null) ? Global.instance() : glob;
68 this.msgQosData = new MsgQosData(this.glob, this.glob.getMsgQosFactory(), MethodName.PUBLISH);
69 this.msgQosData.setMethod(MethodName.PUBLISH);
70 /*
71 // deprecated:
72 long lt = this.glob.getProperty().get("message.lifeTime", -1L);
73 if (lt != -1L) {
74 this.msgQosData.getLifeTimeProp().setValue(lt, PropEntry.CREATED_BY_PROPFILE);
75 }
76 */
77 }
78
79 /**
80 * Default constructor for transient PtP messages.
81 * <p />
82 * To make the message persistent, use the setPersistent() method
83 * @param destination The object containing the destination address.<br />
84 * To add more destinations, us the addDestination() method.
85 */
86 public PublishQos(Global glob, Destination destination) {
87 this(glob);
88 addDestination(destination);
89 }
90
91 /**
92 * @param persistent true = store the message persistently
93 */
94 public PublishQos(Global glob, boolean persistent) {
95 this(glob);
96 setPersistent(persistent);
97 }
98
99 /**
100 * Sets the encoding in the client properties of the content of the message to be published.
101 * Defaults to UTF-8
102 * Is usually not interpreted by xmlBlaster. But special server plugins (like regex filter plugin may want to look into the content and should know the encoding
103 * or the receiving client may want to know.
104 * Note that "text/xml" contents are usually self contained,
105 * the processing instruction tells the xml encoding to the sax/dom parser and this clientProperty is ignored.
106 * @param encoding like "cp1252"
107 */
108 public void setContentEncoding(String encoding) {
109 if (encoding == null || encoding.trim().length() < 1) {
110 if (getData() == null || getData().getClientProperties() == null)
111 return;
112 getData().getClientProperties().remove(Constants.CLIENTPROPERTY_CONTENT_CHARSET);
113 return;
114 }
115 getData().addClientProperty(Constants.CLIENTPROPERTY_CONTENT_CHARSET, encoding.trim());
116 }
117
118 public MsgQosData getData() {
119 return this.msgQosData;
120 }
121
122 /**
123 * As a default setting you can subscribe on all messages (PtP or PubSub).
124 * @param isSubscribable true if Publish/Subscribe style is used<br />
125 * false Only possible for PtP messages to keep PtP secret (you can't subscribe them)
126 */
127 public void setSubscribable(boolean isSubscribable) {
128 this.msgQosData.setSubscribable(isSubscribable);
129 }
130
131 /**
132 * Message priority.
133 * @return priority 0 (=Lowest) - 9 (=Highest)
134 */
135 public PriorityEnum getPriority() {
136 return this.msgQosData.getPriority();
137 }
138
139 /**
140 * Set message priority value, PriorityEnum.NORM_PRIORITY (5) is default.
141 * PriorityEnum.MIN_PRIORITY (0) is slowest
142 * whereas PriorityEnum.MAX_PRIORITY (9) is highest priority.
143 * @see <a href="http://www.xmlBlaster.org/xmlBlaster/doc/requirements/engine.qos.publish.priority.html">The engine.qos.publish.priority requirement</a>
144 */
145 public void setPriority(PriorityEnum priority) {
146 this.msgQosData.setPriority(priority);
147 }
148
149 /**
150 * Send message to subscriber even if the content is the same as the previous?
151 * <br />
152 * Default is that xmlBlaster does send messages to subscribed clients, even the content didn't change.
153 */
154 public void setForceUpdate(boolean force) {
155 this.msgQosData.setForceUpdate(force);
156 }
157
158 /**
159 * Mark a message to be readonly.
160 * <br />
161 * Only the first publish() will be accepted, followers are denied.
162 */
163 public void setReadonly(boolean readonly) {
164 this.msgQosData.setReadonly(readonly);
165 }
166
167 /**
168 * Mark a message to be volatile or not.
169 * <br />
170 * A non-volatile messages stays in memory as long as the server runs or the message expires.<br />
171 * A volatile messages exists only during publish and processing it (doing the updates).<br />
172 * Defaults to false.
173 * <br />
174 * NOTE: This is a convenience method for setLifeTime(0L) and setForceDestroy(false).
175 */
176 public void setVolatile(boolean volatileFlag) {
177 this.msgQosData.setVolatile(volatileFlag);
178 }
179
180 /**
181 * @see #isVolatile()
182 */
183 public boolean isVolatile() {
184 return this.msgQosData.isVolatile();
185 }
186
187 /**
188 * Mark a message to be persistent.
189 */
190 public void setPersistent(boolean persistent) {
191 this.msgQosData.setPersistent(persistent);
192 }
193
194 /**
195 * The message expires after given milliseconds.
196 * @param lifeTime in milliseconds
197 * @see MsgQosData#setLifeTime(long)
198 */
199 public void setLifeTime(long lifeTime) {
200 this.msgQosData.setLifeTime(lifeTime);
201 }
202
203 /**
204 * Control message life cycle on message expiry, defaults to false.
205 * @param forceDestroy true Force message destroy on message expire<br />
206 * false On message expiry messages which are already in callback queues are delivered.
207 */
208 public void setForceDestroy(boolean forceDestroy) {
209 this.msgQosData.setForceDestroy(forceDestroy);
210 }
211
212 /**
213 * Add a destination where to send the message.
214 * <p />
215 * Note you can invoke this multiple times to send to multiple destinations.
216 * <p />
217 * Note that the default lifeTime is set to 0 (PtP are volatile messages as default)
218 * @param destination The loginName of a receiver or some destination XPath query
219 */
220 public void addDestination(Destination destination) {
221 this.msgQosData.addDestination(destination);
222 }
223
224 /**
225 * Access sender name.
226 * @return loginName of sender or null if not known
227 */
228 public SessionName getSender() {
229 return this.msgQosData.getSender();
230 }
231
232 /**
233 * Access sender name.
234 * @param loginName of sender
235 */
236 public void setSender(SessionName sender) {
237 this.msgQosData.setSender(sender);
238 }
239
240 public void setAdministrative(boolean administrative) {
241 this.msgQosData.setAdministrative(administrative);
242 }
243
244 /**
245 * @param state The state to return to the server.
246 * e.g. Contants.STATE_OK, see Constants.java
247 */
248 public void setState(String state) {
249 this.msgQosData.setState(state);
250 }
251
252 public String getState() {
253 return this.msgQosData.getState();
254 }
255
256 /**
257 * @param stateInfo The state info attribute to return to the server.
258 */
259 public void setStateInfo(String stateInfo) {
260 this.msgQosData.setStateInfo(stateInfo);
261 }
262
263 public String getStateInfo() {
264 return this.msgQosData.getStateInfo();
265 }
266
267 /**
268 * Administer/configure the message topic.
269 */
270 public void setTopicProperty(TopicProperty topicProperty) {
271 this.msgQosData.setTopicProperty(topicProperty);
272 }
273
274 /**
275 * Sets a client property (an application specific property) to the
276 * given value
277 * @param key
278 * @param value
279 */
280 public void addClientProperty(String key, Object value) {
281 this.msgQosData.addClientProperty(key, value);
282 }
283
284 public void addClientProperty(String key, boolean value) {
285 this.msgQosData.addClientProperty(key, value);
286 }
287
288 public void addClientProperty(String key, int value) {
289 this.msgQosData.addClientProperty(key, value);
290 }
291
292 public void addClientProperty(String key, byte value) {
293 this.msgQosData.addClientProperty(key, value);
294 }
295
296 public void addClientProperty(String key, long value) {
297 this.msgQosData.addClientProperty(key, value);
298 }
299
300 public void addClientProperty(String key, short value) {
301 this.msgQosData.addClientProperty(key, value);
302 }
303
304 public void addClientProperty(String key, double value) {
305 this.msgQosData.addClientProperty(key, value);
306 }
307
308 public void addClientProperty(String key, float value) {
309 this.msgQosData.addClientProperty(key, value);
310 }
311
312 /**
313 * Read back a property.
314 * @return The client property or null if not found
315 */
316 public ClientProperty getClientProperty(String key) {
317 return this.msgQosData.getClientProperty(key);
318 }
319
320 /**
321 * Converts the data into a valid XML ASCII string.
322 * @return An XML ASCII string
323 */
324 public String toString() {
325 return toXml();
326 }
327
328 /**
329 * Converts the data into a valid XML ASCII string.
330 * @return An XML ASCII string
331 */
332 public String toXml() {
333 return this.msgQosData.toXml();
334 }
335
336 /**
337 * For testing invoke: java org.xmlBlaster.client.PublishQos
338 */
339 public static void main( String[] args ) throws XmlBlasterException
340 {
341 Global glob = new Global(args);
342 {
343 PublishQos qos =new PublishQos(new Global(args), new Destination(new SessionName(glob, "joe")));
344 qos.addDestination(new Destination(new SessionName(glob, "Tim")));
345 qos.setPriority(PriorityEnum.HIGH_PRIORITY);
346 qos.setPersistent(true);
347 qos.setForceUpdate(true);
348 qos.setReadonly(true);
349 qos.setLifeTime(60000);
350 System.out.println(qos.toXml());
351 }
352 {
353 PublishQos qos =new PublishQos(null);
354 System.out.println("Minimal '" + qos.toXml() + "'");
355 }
356 }
357 }
syntax highlighted by Code2HTML, v. 0.9.1