Monday, November 08, 2010 at 12:06 AM.

system.verbs.builtins.tcp.im.builtinDrivers.jabber.code.handleMessage

on handleMessage (connection, mesAdr) {
	<<Changes
		<<5/14/02; 1:51:34 PM by JB
			<<Changelog created.
	<<Given a jabber message, extract the information contained in the message and pass it off to the proper handler. mesAdr is an address pointing to xml.compile'd XML.
		<<Messages relating to being logged in are handled synchronously; all others will be handled asynchronously, so a long <message> or an rpc call won't jam up Jabber for everyone else.
	on mungeId ( idStr ) {
		// this munges the id string into a semaphore name, this scriptlet will be copied into several places.
		if typeOf ( idStr ) == addressType {
			idStr = nameOf ( idStr^ )};
		return "JabberIQTagSem" + idStr};
	local ( here = mesAdr, tagName = xml.convertToDisplayName ( nameOf ( here^[1] ) ) );
	tagName = string.lower ( tagName );
	case tagName {
		"iq" { // http://docs.jabber.org/jpg/html/main.html#CH-IQNS
			// the iq is used for a lot of messages, so we need to keep digging to see which one it is
			local ( iq, query, namespace );
			iq = xml.getAddress(here, "iq" );
			try {
				query = xml.getAddress(iq, "query")};
			try {
				id = xml.getAttribute ( iq, "id" )}
			else {
				id = ""};
			try {
				namespace = xml.getAttribute ( query, "xmlns" );
				namespace = namespace^}
			else {
				namespace = ""};
			case namespace {
				"" { // successful login (anything else?)
					tcp.im.builtinDrivers.jabber.code.handlers.iqLoggedIn ( connection, mesAdr, iq, query  )};
				"jabber:iq:auth" { // account registration issues, failed login
					tcp.im.builtinDrivers.jabber.code.handlers.iqRegister ( connection, mesAdr, iq, query )};
				"jabber:iq:register" { // account registration issues
					tcp.im.builtinDrivers.jabber.code.handlers.iqRegister ( connection, mesAdr, iq, query )};
				"jabber:iq:roster" { // who this account is subscribed to
					tcp.im.builtinDrivers.jabber.code.handlers.iqRoster ( connection, mesAdr, iq, query )};
				"jabber:iq:version" { // version information requests
					try {
						tcp.im.builtinDrivers.jabber.code.handlers.iqVersion ( connection, mesAdr, iq, query )}}}
			else { // none of the namespaces matched, so look for handlers
				local ( handlers = tcp.im.builtinDrivers.jabber.code.getHandlerTable(connection, "iq", namespace ) );
				if defined ( handlers^ ) {
					for handler in handlers {
						while typeOf ( handler^ ) == addressType {
							handler = handler^};
						try {
							handler^ (iq, query, connection)}}}};
			
			// if there's an ID and the type is result (i.e., a returning query), and the id table exists, unlock the corresponding semaphore
			// justification for this is in a comment in jabber.idTables.create
			try {
				local ( id = xml.getAttributeValue ( iq, "id" ), mesType = xml.getAttributeValue ( iq, "type" ) );
				if mesType == "result" and defined ( tcp.im.builtinDrivers.jabber.code.idTables.getAdr ( id )^ ) {
					semaphore.unlock ( mungeId ( id ) )}}};
		"message" {
			tcp.im.builtinDrivers.jabber.code.handlers.message ( connection, mesAdr )};
		"presence" {
			tcp.im.builtinDrivers.jabber.code.handlers.presence ( connection, mesAdr )}}};
handleMessage ( @workspace.x )



This listing is for code that runs in the OPML Editor environment. I created these listings because I wanted the search engines to index it, so that when I want to look up something in my codebase I don't have to use the much slower search functionality in my object database. Dave Winer.