📄 connectqossaxfactory.java
字号:
/*------------------------------------------------------------------------------Name: ConnectQosSaxFactory.javaProject: xmlBlaster.orgCopyright: xmlBlaster.org, see xmlBlaster-LICENSE fileComment: Parsing connect QoS------------------------------------------------------------------------------*/package org.xmlBlaster.util.qos;import java.util.Properties;import java.util.logging.Logger;import org.xmlBlaster.util.Global;import org.xmlBlaster.util.qos.address.Address;import org.xmlBlaster.util.qos.address.AddressBase;import org.xmlBlaster.util.qos.address.CallbackAddress;import org.xmlBlaster.util.def.Constants;import org.xmlBlaster.util.qos.storage.ClientQueueProperty;import org.xmlBlaster.util.qos.storage.CbQueueProperty;import org.xmlBlaster.util.qos.address.ServerRef;import org.xmlBlaster.util.XmlBlasterException;import org.xmlBlaster.authentication.plugins.I_SecurityQos;import org.xmlBlaster.util.SessionName;import org.xml.sax.Attributes;/** * This class encapsulates the qos of a login() or connect(). * <p /> * So you don't need to type the 'ugly' XML ASCII string by yourself. * After construction access the ASCII-XML string with the toXml() method. * <br /> * A typical <b>connect QoS</b> could look like this:<br /> * <pre> *<qos> * <securityService type="htpasswd" version="1.0"> * <![CDATA[ * <user>joe</user> * <passwd>secret</passwd> * ]]> * </securityService> * * <session name='/node/heron/client/joe' timeout='3600000' maxSessions='10' clearSessions='false' reconnectSameClientOnly='false'/> * * <ptp>true</ptp> <!-- Allow receiving PtP messages (no SPAM protection) --> * * <duplicateUpdates>true</duplicateUpdates> * * <!-- The client side queue (is ignored on server side): --> * <queue relating='client' type='CACHE' version='1.0' maxEntries='1000' maxBytes='4000' onOverflow='exception'> * <address type='IOR'> * IOR:10000010033200000099000010.... * </address> * <queue> * * <!-- Configures the server side callback queue: --> * <queue relating='callback' type='CACHE' version='1.0' maxEntries='1000' maxBytes='4000' onOverflow='deadMessage'> * <callback type='IOR' sessionId='4e56890ghdFzj0'> * IOR:10000010033200000099000010.... * <burstMode collectTime='400' /> * </callback> * </queue> *</qos> * </pre> * NOTE: As a user of the Java client helper classes (client.I_XmlBlasterAccess) * you don't need to create the <pre><callback></pre> element. * This is generated automatically from I_XmlBlasterAccess when instantiating * the callback driver. * * <p /> * * A typical <b>connect return QoS</b> could look like this (this is the acknowledge returned by * the server to the client on successful connect):<br /> * <pre> *<qos> * <securityService type="htpasswd" version="1.0"> * <![CDATA[ * <user>joe</user> * <passwd>secret</passwd> * ]]> * </securityService> * * <session name='/node/heron/client/joe/-9' timeout='3600000' maxSessions='10' clearSessions='false' * clearSessions='false' sessionId='sessionId:192.168.1.4-null-1042823803521-2074317763-3'/> * * <reconnected>false</reconnected> <!-- Has the client reconnected to an existing session? --> * * <!-- The server side callback queue: --> * <queue relating='callback' type='CACHE' version='1.0' maxEntries='1000' maxBytes='4000' onOverflow='deadMessage'> * <callback type='XMLRPC' bootstrapHostname='192.168.1.4' sessionId='4e56890ghdFzj0'> * http://192.168.1.4:8081/ * <burstMode collectTime='400' /> * </callback> * <queue> *</qos> * </pre> * @see org.xmlBlaster.test.classtest.ConnectQosTest * @see <a href="http://www.xmlblaster.org/xmlBlaster/doc/requirements/interface.connect.html">connect interface</a> */public final class ConnectQosSaxFactory extends org.xmlBlaster.util.XmlQoSBase implements I_ConnectQosFactory{ private final Global glob; private static Logger log = Logger.getLogger(ConnectQosSaxFactory.class.getName()); private ConnectQosData connectQosData; // helper flags for SAX parsing //private boolean inServerRef; private boolean inQueue; private boolean inSecurityService; //private boolean inSession; private boolean inCallback; private boolean inAddress; /** Helper for SAX parsing */ private ServerRef tmpServerRef; private CbQueueProperty tmpCbProp; private CallbackAddress tmpCbAddr; private ClientQueueProperty tmpProp; private Address tmpAddr; protected String tmpSecurityPluginType; protected String tmpSecurityPluginVersion; //private boolean inIsPersistent = false; /** */ public ConnectQosSaxFactory(Global glob) { super(glob); this.glob = glob; } /** * Parses the given xml Qos and returns a ConnectQosData holding the data. * Parsing of connect() and connect-return QoS is supported here. * This call is thread safe if not intermixed with <tt>getConnectQosData()</tt> calls. * @param the XML based ASCII string */ public synchronized ConnectQosData readObject(String xmlQos) throws XmlBlasterException { if (xmlQos == null) { xmlQos = "<qos/>"; } this.inQueue = false; this.inSecurityService = false; //this.inSession = false; this.inCallback = false; this.inAddress = false; this.tmpServerRef = null; this.tmpCbProp = null; this.tmpCbAddr = null; this.tmpProp = null; this.tmpAddr = null; this.tmpSecurityPluginType = null; this.tmpSecurityPluginVersion = null; //this.inIsPersistent = false; this.connectQosData = new ConnectQosData(glob, this, xmlQos, null); if (!isEmpty(xmlQos)) // if possible avoid expensive SAX parsing init(xmlQos); // use SAX parser to parse it (is slow) return this.connectQosData; } /** * This is NOT thread safe so you need a new factory for each parse. * Use this variant if you have a bigger xml markup and want to delegate * startElement(), endElement() calls to this. * PRECONDITION: Call setConnectQosData() first! */ public ConnectQosData getConnectQosData() { return this.connectQosData; } /** If a delegate call startElement() directly */ public void setConnectQosData(ConnectQosData data) { this.connectQosData = data; } /** * Start element, event from SAX parser. * <p /> * @param name Tag name * @param attrs the attributes of the tag */ public void startElement(String uri, String localName, String name, Attributes attrs) { startElement(uri, localName, name, this.character, attrs); } /** * Start element from SAX parsing, call as delegate delivers the character */ public void startElement(String uri, String localName, String name, StringBuffer character, Attributes attrs) { if (this.clientPropertyTagNames.contains(name) && character.toString().trim().length() > 0) { // If e.g. email address is written before <attribute> tag if (inCallback) tmpCbAddr.setRawAddress(character.toString().trim()); if (inAddress) tmpAddr.setRawAddress(character.toString().trim()); } if (super.startElementBase(uri, localName, name, attrs) == true) return; //if (log.isLoggable(Level.FINE)) log.trace(ME, "Entering startElement for uri=" + uri + " localName=" + localName + " name=" + name); if (name.equalsIgnoreCase("serverRef")) { //this.inServerRef = true; String tmp = character.toString().trim(); // The address (if before inner tags) String type = null; if (attrs != null) { int len = attrs.getLength(); for (int i = 0; i < len; i++) { if( attrs.getQName(i).equalsIgnoreCase("type") ) { type = attrs.getValue(i).trim(); break; } } } if (type == null) { log.severe("Missing 'serverRef' attribute 'type' in login-qos"); type = AddressBase.DEFAULT_type;// Since 1.0.7 "SOCKET", before "IOR"; } tmpServerRef = new ServerRef(type); if (tmp.length() > 0) { tmpServerRef.setAddress(tmp); character.setLength(0); } return; } if (inCallback) { tmpCbAddr.startElement(uri, localName, name, character, attrs); return; } if (name.equalsIgnoreCase("callback")) { inCallback = true; if (!inQueue) { tmpCbProp = new CbQueueProperty(glob, Constants.RELATING_CALLBACK, null); // Use default queue properties for this callback address this.connectQosData.setSessionCbQueueProperty(tmpCbProp); } tmpCbAddr = new CallbackAddress(glob); tmpCbAddr.startElement(uri, localName, name, character, attrs); tmpCbProp.setCallbackAddress(tmpCbAddr); return; } if (name.equalsIgnoreCase("address")) { inAddress = true; boolean accepted=true; if (!inQueue) { tmpProp = new ClientQueueProperty(glob, null); // Use default queue properties for this connection address accepted = this.connectQosData.addClientQueueProperty(tmpProp); } tmpAddr = new Address(glob); tmpAddr.startElement(uri, localName, name, character, attrs); if (accepted) { tmpProp.setAddress(tmpAddr); } return; } if (name.equalsIgnoreCase("queue")) { inQueue = true; if (inCallback) { log.severe("<queue> tag is not allowed inside <callback> tag, element ignored."); character.setLength(0); return; } if (inAddress) { log.severe("<queue> tag is not allowed inside <address> tag, element ignored."); character.setLength(0); return; } String related = attrs.getValue("relating"); if (Constants.RELATING_CLIENT.equalsIgnoreCase(related)) { tmpProp = new ClientQueueProperty(glob, null); tmpProp.startElement(uri, localName, name, attrs); /*boolean accepted = */this.connectQosData.addClientQueueProperty(tmpProp); } else if (Constants.RELATING_CALLBACK.equalsIgnoreCase(related)) { tmpCbProp = new CbQueueProperty(glob, Constants.RELATING_CALLBACK, null); tmpCbProp.startElement(uri, localName, name, attrs); this.connectQosData.setSessionCbQueueProperty(tmpCbProp); } else if (Constants.RELATING_SUBJECT.equalsIgnoreCase(related)) { tmpCbProp = new CbQueueProperty(glob, Constants.RELATING_SUBJECT, null); tmpCbProp.startElement(uri, localName, name, attrs); this.connectQosData.setSubjectQueueProperty(tmpCbProp); } else { log.warning("The given relating='" + related + "' is not supported, configuration for '" + related + "' is ignored"); } character.setLength(0); return; } if (name.equalsIgnoreCase("securityService")) { inSecurityService = true; boolean existsTypeAttr = false; boolean existsVersionAttr = false; if (attrs != null) { int len = attrs.getLength(); int ii=0; for (ii = 0; ii < len; ii++) { if (attrs.getQName(ii).equalsIgnoreCase("type")) { existsTypeAttr = true; tmpSecurityPluginType = attrs.getValue(ii).trim(); } else if (attrs.getQName(ii).equalsIgnoreCase("version")) { existsVersionAttr = true; tmpSecurityPluginVersion = attrs.getValue(ii).trim(); } } } if (!existsTypeAttr) log.severe("Missing 'type' attribute in login-qos <securityService>"); if (!existsVersionAttr) log.severe("Missing 'version' attribute in login-qos <securityService>"); character.setLength(0); // Fall through and collect xml, will be parsed later by appropriate security plugin } if (name.equalsIgnoreCase("session")) { //this.inSession = true; if (attrs != null) { int len = attrs.getLength(); int ii=0; SessionQos sessionQos = this.connectQosData.getSessionQos(); for (ii = 0; ii < len; ii++) { if (attrs.getQName(ii).equalsIgnoreCase("name")) { if (glob.isServerSide()) { // Force the server node ID on connect sessionQos.setSessionName(new SessionName(glob, glob.getNodeId(), attrs.getValue(ii).trim())); } else { sessionQos.setSessionName(new SessionName(glob, attrs.getValue(ii).trim())); } } else if (attrs.getQName(ii).equalsIgnoreCase("timeout")) sessionQos.setSessionTimeout((new Long(attrs.getValue(ii).trim())).longValue()); else if (attrs.getQName(ii).equalsIgnoreCase("maxSessions")) sessionQos.setMaxSessions((new Integer(attrs.getValue(ii).trim())).intValue());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -