for writing Jabber components in Java
Java Library Dependencies
Included Libraries and Tools
Why another Java-Jabber communications API? I tried the current offerings and each was far enough away from my criteria to merit (drum-roll please) yet another API.
In short, here are the design drivers and requirements for Yaja!...
The first use case for Yaja! will be building a Jabber component. As such, the majority of development will cater to component requirements. If you are building a Java end-user client, you should evaluate the other Java APIs for suitability to your task. You can find the Java projects at http://www.jabberstudio.org/. Since Yaja! is a general XMPP framework, you may very well find it satisfies your needs.
As Jabber streams XMPP packets to Yaja!, a SAX parser generates a series of SAX events. Yaja! does not define how these are interpreted, and instead allows one or more transformers act on the SAX event stream.
Transformers take the SAX events and build object graphs to represent the packets. Yaja! includes a sample DOM builder for converting XMPP packets to DOM documents.
The DOM transformer supports a listener model to allow interested parties to register for incoming packet notifications. Since XMPP typically involves request/response interactions, a special DomPacketSender class is provided which sends a packet and then listens for a response.
Sending packets can be as simple as writing raw XML to the XMPP session. The only requirement is that the entire packet is written at one time to avoid interleaving fragmented packets from multiple writers.
Yaja! is also thread safe to allow multiple readers and writers to operate on a common XMPP session.
For session lifecycle events such as connection starting, session authenticated, and connection closed, an XmppSessionListener is provided. Interested parties can register with the XMPP session to receive events.
The following code opens a Jabber session:
XmppSession session = new XmppSession( "localhost", 1213 , XmppSession.COMPONENT_ACCEPT_NAMESPACE ); session.open();
Once the session is established, Yaja! can send XMPP packets to the server, or process incoming packets from the server.
To send XMPP packets to the server, simply call the write() method on the XmppSession object.
session.write( "<handshake>1ef6782322</handshake>" );
However, the XMPP send will usually be handled by a higher level helper class such as the DomPacketSender.
Element response = new DomPacketSender( transformer ).query( request );
To receive an XMPP packet, you need to register with an XMPP transformer. This is where the power (and simplicity) of Yaja! lies; Yaja! uses SAX to generate XML events from the incoming XMPP stream. One or more transformers consumer the XML event stream and build in-memory representations.
A reference Xmpp2DomTransformer is included with Yaja! The transformer was written in under 150 lines of code (complete with comments) to proof the integration simplicity. An example using the Xmpp2DomTransformer follows...
new Xmpp2DomTransformer( session );
You are free to write your own transfomers and register as many as you like. There is also a listener framework for monitoring XMPP stream lifecycle events such as stream opening and closing.
Combining the code from the overview above results in the following:
// open connection XmppSession session = new XmppSession( "localhost", 1213, XmppSession.COMPONENT_ACCEPT_NAMESPACE ); session.open(); // we'd like to see DOM packets, so let's create a DOM transformer Xmpp2DomTransformer transformer = new Xmpp2DomTransformer( session ); // send the accept component handshake String sSessionId = session.getAttribute( "id" ); HandshakeRequest request = new HandshakeRequest( sSessionId, "secret" ); Element response = new DomPacketSender( transformer ).query( request );
For a more complete example, please review the com.realtime.xmpp.examples.EchoComponent class. Windows users should be able to execute the echo.bat file from the win32 directory to start the component.
Add the component to the service list. Service elements are children of the <jabber> element. Insert the following XML into the same area as the other services are defined:
<service id="yaja.localhost"> <accept> <ip/> <port>1213</port> <secret>secret</secret> </accept> </service>
The following XML will make the component browseable by clients. Add the following the the <browse> section of jabber.xml.
<service type="yaja" jid="yaja.localhost" name="Yaja"> <ns>jabber:iq:gateway</ns> <ns>jabber:iq:register</ns> <ns>jabber:iq:time</ns> <ns>jabber:iq:version</ns> </service>
Add the following to the the <jsm> element to receive a copy of all presence messages.
<presence> <bcc>yaja.localhost</bcc> </presence>
After you have made the above changes, be sure to restart the Jabber server.
Special thanks goes to Daniel Noll for many great suggestions and being brave enough to test the code early on.
This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA