📄 msgqosdata.java
字号:
* Setting to 0 will behave as a volatile message (see setVolatile()) * and the message will be invisible directly after being pushed into the subscribers * callback queues, in the callback queues it will stay until retrieved by the subscriber. * <p> * Setting it to a value > 0 will expire the message after the given milliseconds, * even if they remain in any callback queue. */ public void setLifeTime(long lifeTime) { this.lifeTime.setValue(lifeTime); } /** * @return Milliseconds until message expiration (from now) or -1L if forever * if 0L the message is expired */ public long getRemainingLife() { if (getLifeTime() > 0L && getLifeTime() < Long.MAX_VALUE && getRcvTimestamp() != null) { long ttl = getRcvTimestamp().getMillis() + getLifeTime() - System.currentTimeMillis(); return ( ttl < 0L ) ? 0L : ttl; } else return -1L; } /** * This is the value delivered in the QoS (as it was calculated by the server on sending) * and is NOT dynamically recalculated. * So trust this value only if your client clock is out of date (or not trusted) and * if you know the message sending latency is not too big. * @return Milliseconds until message expiration (from now) or -1L if forever * if 0L the message is expired */ public long getRemainingLifeStatic() { return this.remainingLifeStatic; } public void setRemainingLifeStatic(long remainingLifeStatic) { this.remainingLifeStatic = remainingLifeStatic; } /** * Calculates if we are expired */ public boolean isExpired() { if (getLifeTime() == Long.MAX_VALUE || getLifeTime() <= 0L) { return false; // lifes forever } if (getRcvTimestamp() == null) { return false; } if (isExpired) { // cache return true; } isExpired = System.currentTimeMillis() > (getRcvTimestamp().getMillis() + getLifeTime()); return isExpired; } /* if (lifeTime < 0L && getMaxLifeTime() < 0L) this.expirationTimestamp = Long.MAX_VALUE; else if (lifeTime >= 0L && getMaxLifeTime() < 0L) this.expirationTimestamp = getRcvTimestamp().getMillis() + lifeTime; else if (lifeTime < 0L && getMaxLifeTime() >= 0L) this.expirationTimestamp = getRcvTimestamp().getMillis() + getMaxLifeTime(); else if (lifeTime >= 0L && getMaxLifeTime() >= 0L) { if (lifeTime <= getMaxLifeTime()) this.expirationTimestamp = getRcvTimestamp().getMillis() + lifeTime; else this.expirationTimestamp = getRcvTimestamp().getMillis() + getMaxLifeTime(); } */ /** * The server default for max. span of life, * adjustable with property "message.maxLifeTime" * @return max span of life for a message */ public static long getMaxLifeTime() { return maxLifeTime; } /** * Tagged form of message receive, e.g.:<br /> * <rcvTimestamp nanos='1007764305862000004'/> * * @see org.xmlBlaster.util.Timestamp */ public String getXmlRcvTimestamp() { if (getRcvTimestamp() == null) return ""; if (receiveTimestampHumanReadable) return getRcvTimestamp().toXml(null, true); else return getRcvTimestamp().toXml(); } /** * Human readable form of message receive time in xmlBlaster server, * in SQL representation e.g.:<br /> * 2001-12-07 23:31:45.862000004 * @deprecated Use getXmlRcvTimestamp() */ public String getRcvTime() { return (rcvTimestamp != null) ? rcvTimestamp.toString() : ""; } /** * Control message life cycle on message expiry, defaults to false. * @param forceDestroy true Force message destroy on message expire<br /> * false On message expiry messages which are already in callback queues are delivered. * @see <a href="http://www.xmlBlaster.org/xmlBlaster/doc/requirements/engine.qos.publish.isVolatile.html">The engine.qos.publish.isVolatile requirement</a> */ public void setForceDestroy(boolean forceDestroy) { this.forceDestroy.setValue(forceDestroy); } /** * @return true/false, defaults to false */ public boolean isForceDestroy() { return this.forceDestroy.getValue(); } public PropBoolean getForceDestroyProp() { return this.forceDestroy; } /** * Marks a message to be administrative only, in this case the topic is configured only. * Note the administrative messages have a default priority of MAX_PRIORITY * @param administrative true The message is only used to configure the topic<br /> * false The message contains useful content (and may as initial publish configure the topic as well) * @see org.xmlBlaster.util.def.PriorityEnum */ public void setAdministrative(boolean administrative) { this.administrative.setValue(administrative); if (!this.priorityIsModified) { this.priority = (administrative) ? PriorityEnum.MAX_PRIORITY : PriorityEnum.NORM_PRIORITY; } } /** * @return true/false, defaults to false */ public boolean isAdministrative() { return this.administrative.getValue(); } public PropBoolean getAdministrativeProp() { return this.administrative; } /** * Get all the destinations of this message. * This should only be used with PTP style messaging<br /> * Check <code>if (isPtp()) ...</code> before calling this method * * @return a valid ArrayList containing 0 - n Strings with destination names (loginName of clients)<br /> * null if Publish/Subscribe style is used */ public ArrayList getDestinations() { return this.destinationList; } public int getNumDestinations() { if (this.destinationList == null) { return 0; } return this.destinationList.size(); } /** * @return The destinations in array form */ public Destination[] getDestinationArr() { if (this.destinationArrCache == null) { ArrayList dd = this.destinationList; if (dd == null) { this.destinationArrCache = EMPTY_DESTINATION_ARR; } else { this.destinationArrCache = (Destination[])dd.toArray(new Destination[dd.size()]); } } return this.destinationArrCache; } /** * Add a destination. * Note that the default lifeTime is set to 0 (PtP are volatile as default) */ public void addDestination(Destination destination) { if (destination == null) return; if (this.destinationList == null) this.destinationList = new ArrayList(); this.destinationArrCache = null; this.destinationList.add(destination); if (!this.lifeTime.isModified()) { // Change default setting for PtP to 'volatile' this.lifeTime.setValue(0L, PropEntry.CREATED_BY_DEFAULT); } } /** * Remove a destination. */ public void removeDestination(Destination destination) { if (destination == null || this.destinationList == null) return; this.destinationArrCache = null; this.destinationList.remove(destination); if (this.destinationList.size() < 1) { this.destinationList = null; } } /** * The getTopicProperty() creates an initial TopicHandler, * this method allows to check without creation */ public boolean hasTopicProperty() { return this.topicProperty != null; } /** * The configuration for the TopicHandler (topic) * @return never null (a default is created if none is available) */ public TopicProperty getTopicProperty() { if (this.topicProperty == null) { this.topicProperty = new TopicProperty(glob); } return this.topicProperty; } /** * @param The new topicProperty, usually you should create the instance with getTopicProperty() * to not loose any readonly settings.<br /> * null resets the settings */ public void setTopicProperty(TopicProperty topicProperty) { this.topicProperty = topicProperty; } /** * Dump the QoS to a flattened JXPath representation. * <p> * This is experimental code for the simple Applet client * </p> * <pre> * /qos/rcvTimestamp/@nanos -> 1042815836675000001 * /qos/methodName/text() -> update * /qos/clientProperty[@name='myAge']/text() -> 12 * /qos/state/@id -> OK * </pre> * <p> * Currently only an UpdateQos dump is supported * @see <a href="http://jakarta.apache.org/commons/jxpath/">Apache JXPath</a> */ public Hashtable toJXPath() { /* Problems with current java objects / JXPath mapping: 1. <persistent />: "/qos/persistent/text()" -> returns nothing instead of true 2. getState() returns the <state id=''> instead of a state object with state.getId(), state.getInfo() 3. "/qos/route/node/@id" returns three nodes -> we need something like nodeList 4. Priority is returned as '4' or as 'LOW': With java this is handled by PriorityEnum.java */ Hashtable map = new Hashtable(); map.put("/qos/rcvTimestamp/@nanos", ""+getRcvTimestamp()); map.put("/qos/rcvTimestamp/text()", ""+getRcvTime()); MethodName methodName = getMethod(); if (methodName != null) map.put("/qos/methodName/text()", methodName.toString()); map.put("/qos/persistent/text()", ""+isPersistent()); Map pMap = getClientProperties(); Iterator it = pMap.keySet().iterator(); while (it.hasNext()) { String key = (String)it.next(); ClientProperty p = (ClientProperty)pMap.get(key); map.put("/qos/clientProperty[@name='"+key+"']/text()", p.getValueRaw()); map.put("/qos/clientProperty[@name='"+key+"']/@type", p.getType()); map.put("/qos/clientProperty[@name='"+key+"']/@encoding", p.getEncoding()); } if (isUpdate() || isGet()) { org.xmlBlaster.util.cluster.RouteInfo[] routes = getRouteNodes(); for (int i=0; i<routes.length; i++) { map.put("/qos/route/node[@id='"+routes[i].getId()+"']/@stratum", ""+routes[i].getStratum()); map.put("/qos/route/node[@id='"+routes[i].getId()+"']/@timestamp", ""+routes[i].getTimestamp()); map.put("/qos/route/node[@id='"+routes[i].getId()+"']/@dirtyRead", ""+routes[i].getDirtyRead()); } if (getState() != null) map.put("/qos/state/@id", getState()); if (getStateInfo() != null) map.put("/qos/state/@info", getStateInfo()); } if (isUpdate()) { if (getSubscriptionId() != null) map.put("/qos/subscribe/@id", getSubscriptionId()); map.put("/qos/queue/@index", ""+getQueueIndex()); map.put("/qos/queue/@size", ""+getQueueSize()); map.put("/qos/redeliver/text()", ""+getRedeliver()); } SessionName sender = getSender(); if (sender != null) { map.put("/qos/sender/text()", sender.toString()); } map.put("/qos/expiration/@lifeTime", ""+getLifeTime()); map.put("/qos/expiration/@remainingLife", ""+getRemainingLife()); if (isPublish()) { // TopicProperty ? } return map; } /** * Dump state of this object into a XML ASCII string. * <br> * @return internal state of the message QoS as a XML ASCII string */ public String toXml() { return toXml((String)null, (Properties)null); } public String toXml(String extraOffset) { return toXml(extraOffset, (Properties)null); } /** * Dump state of this object into a XML ASCII string. * <br> * @param extraOffset indenting of tags for nice output * @param forceReadable If true, any base64 is decoded to be more human readable * @return internal state of the message QoS as a XML ASCII string */ public String toXml(String extraOffset, Properties props) { return this.factory.writeObject(this, extraOffset, props); } /** * Returns a partly deep clone, you can change safely all basic or immutable types * like boolean, String, int. * Currently TopicProperty is not cloned (so don't change it) */ public Object clone() { MsgQosData newOne = null; //try { newOne = (MsgQosData)super.clone(); synchronized(this) { newOne.subscribable = (PropBoolean)this.subscribable.clone(); newOne.forceUpdate = (PropBoolean)this.forceUpdate.clone(); newOne.lifeTime = (PropLong)this.lifeTime.clone(); newOne.administrative = (PropBoolean)this.administrative.clone(); newOne.forceDestroy = (PropBoolean)this.forceDestroy.clone(); } return newOne; //} //catch (CloneNotSupportedException e) { // return null; //} } /** * Sets the global object (used when deserializing the object) */ public void setGlobal(Global glob) { super.setGlobal(glob); this.factory = glob.getMsgQosFactory(); } public static void main(String[] args) { MsgQosData md = new MsgQosData(new Global(args), MethodName.UPDATE); Map map = md.toJXPath(); Iterator it = map.keySet().iterator(); while (it.hasNext()) { String key = (String)it.next(); System.out.println(key + " -> '" + map.get(key) + "'"); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -