Package org.activemq.transport.jabber

Source Code of org.activemq.transport.jabber.JabberWireFormat

/**
*
* Copyright 2004 Protique Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**/
package org.activemq.transport.jabber;

import org.activemq.io.AbstractWireFormat;
import org.activemq.io.WireFormat;
import org.activemq.io.util.ByteArray;
import org.activemq.message.ActiveMQBytesMessage;
import org.activemq.message.ActiveMQDestination;
import org.activemq.message.ActiveMQMessage;
import org.activemq.message.ActiveMQObjectMessage;
import org.activemq.message.ActiveMQTextMessage;
import org.activemq.message.ConnectionInfo;
import org.activemq.message.ConsumerInfo;
import org.activemq.message.Packet;
import org.activemq.util.IdGenerator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.jms.Destination;
import javax.jms.JMSException;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Serializable;
import java.net.InetAddress;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
* A wire format which uses XMPP format of messages
*
* @version $Revision: 1.1 $
*/
public class JabberWireFormat extends AbstractWireFormat {
    private static final Log log = LogFactory.getLog(JabberWireFormat.class);

    private static final String NAMESPACE = "http://etherx.jabber.org/streams";
    private static final String QUEUE_PREFIX = "queue:";
    private static final String TOPIC_PREFIX = "topic:";
    private static final String TEMP_QUEUE_PREFIX = "tempQueue:";
    private static final String TEMP_TOPIC_PREFIX = "tempTopic:";

    private static final QName STREAM_QNAME = new QName(NAMESPACE, "stream", "stream");
    private static final QName MESSAGE_QNAME = new QName("jabber:client","message","message");
    private static final QName AUTH_QNAME = new QName("jabber:iq:auth", "query", "query");

    private IdGenerator idGenerator = new IdGenerator();
    private String clientID = idGenerator.generateId();
    private ConnectionInfo connectionInfo;
    private PrintWriter writer;
    private String userName;
    private boolean validStream = false;


    public WireFormat copy() {
        return new JabberWireFormat();
    }

    public Packet readPacket(int firstByte, DataInput in) throws IOException {
        return null/** TODO */
    }


    /**
     * Reads a packet from the XML stream
     * @param reader
     * @param returnPackets
     * @throws XMLStreamException
     * @throws JMSException
     */
    public void readPacket(XMLStreamReader reader, List returnPackets) throws XMLStreamException, JMSException {
        String sessionId = getAttributeValue("id", reader);
       
        if (reader.next() == XMLStreamConstants.START_ELEMENT) {
           
            QName name = reader.getName();
           
            if (!validStream) {
                if (name.equals(STREAM_QNAME)) {
                    validStream = true;
                }
                else {
                    String errStr = "Bad initial QName for stream. Received: " + name + " while expecting: "
                            + STREAM_QNAME;
                    log.warn(errStr);
                    throw new JMSException(errStr);
                }
            }
            else {
                QName test = new QName("jabber:iq:auth", "query", "query");
               
                if (name.equals(AUTH_QNAME)) {
                    if (reader.hasNext() && reader.next()==XMLStreamConstants.START_ELEMENT){
                        name = reader.getName();
                        this.userName = reader.getElementText();
                       
                        //skip past the end
                        if (reader.hasNext()) {
                            reader.next();
                        }
                        if (reader.hasNext() && reader.next()==XMLStreamConstants.START_ELEMENT){
                            if (sessionId != null){
                                writer.println(" <iq id='" + sessionId +"' type='result'/>");
                                writer.flush();
                             }
                        }else {
                            //write back a request for the password
                            writer.println("<iq id='" + sessionId + "'");
                            writer.println(" type = 'result'>");
                            writer.println("<query xmlns='jabber:iq:auth'><username>" + this.userName + "</username><password/><digest/><resource/></query></iq>");
                            writer.flush();
                            returnPackets.add(createConnectionInfo());
                            returnPackets.add(createConsumerPacket());
                        }
                    }   
                }else if (name.equals(MESSAGE_QNAME)){
                    Packet pack = readMessage(reader);
                    if (pack != null){
                        returnPackets.add(pack);
                    }
                }else {
                    //general catch all - just say ok ..
                    if (sessionId != null){
                       writer.println(" <iq id='" + sessionId +"' type='result'/>");
                       writer.flush();
                    }
                }
            }
        }
    }
   
    private String getAttributeValue(String attributeName, XMLStreamReader reader) {
        String result = null;
        for (int i = 0;i < reader.getAttributeCount();i++) {
            if (reader.getAttributeName(i).toString().equals(attributeName)) {
                result = reader.getAttributeValue(i);
                break;
            }
        }
        return result;
    }
   
  


    public Packet writePacket(Packet packet, DataOutput out) throws IOException, JMSException {
        switch (packet.getPacketType()) {
            case Packet.ACTIVEMQ_MESSAGE:
                writeMessage((ActiveMQMessage) packet, "", out);
                break;

            case Packet.ACTIVEMQ_TEXT_MESSAGE:
                writeTextMessage((ActiveMQTextMessage) packet, out);
                break;

            case Packet.ACTIVEMQ_BYTES_MESSAGE:
                writeBytesMessage((ActiveMQBytesMessage) packet, out);
                break;

            case Packet.ACTIVEMQ_OBJECT_MESSAGE:
                writeObjectMessage((ActiveMQObjectMessage) packet, out);
                break;

            case Packet.ACTIVEMQ_CONNECTION_INFO:
               
            case Packet.ACTIVEMQ_MAP_MESSAGE:
            case Packet.ACTIVEMQ_STREAM_MESSAGE:


            case Packet.ACTIVEMQ_BROKER_INFO:
            case Packet.ACTIVEMQ_MSG_ACK:
            case Packet.CONSUMER_INFO:
            case Packet.DURABLE_UNSUBSCRIBE:
            case Packet.INT_RESPONSE_RECEIPT_INFO:
            case Packet.PRODUCER_INFO:
            case Packet.RECEIPT_INFO:
            case Packet.RESPONSE_RECEIPT_INFO:
            case Packet.SESSION_INFO:
            case Packet.TRANSACTION_INFO:
            case Packet.XA_TRANSACTION_INFO:
            default:
                log.debug("Ignoring message type: " + packet.getPacketType() + " packet: " + packet);
        }
        writer.flush();
        return null;
    }

    /**
     * Can this wireformat process packets of this version
     *
     * @param version the version number to test
     * @return true if can accept the version
     */
    public boolean canProcessWireFormatVersion(int version) {
        return true;
    }

    /**
     * @return the current version of this wire format
     */
    public int getCurrentWireFormatVersion() {
        return 1;
    }

    public PrintWriter getWriter() {
        return writer;
    }

    public void setWriter(PrintWriter writer) {
        this.writer = writer;
    }

    // Implementation methods
    //-------------------------------------------------------------------------
    protected Packet createConnectionInfo() {
        connectionInfo = new ConnectionInfo();
        connectionInfo.setStarted(true);
        connectionInfo.setClientId(this.clientID);
        connectionInfo.setClientVersion("" + getCurrentWireFormatVersion());
        connectionInfo.setUserName(userName);
        return connectionInfo;
    }
   
    protected Packet createConsumerPacket(){
        ConsumerInfo info = new ConsumerInfo();
        info.setClientId(this.clientID);
        info.setConsumerNo(0);
        info.setStarted(true);
        info.setStartTime(System.currentTimeMillis());
        info.setDestination(createDestination("chat",this.userName));
        return info;
    }


   
   
    protected void initialize() throws IOException {
        //start the stream -
        String hostName = InetAddress.getLocalHost().toString();
        writer.println("<?xml version='1.0'?>");
        writer.println("<stream:stream");
        writer.println("  xmlns='jabber:client'");
        writer.println("  xml:lang='en'");
        writer.println("  xmlns:stream='http://etherx.jabber.org/streams'");
        writer.println("  from='" + hostName + "'");
        writer.println("  id='" + clientID + "'>");
        writer.flush();
   }

    protected Packet readMessage(XMLStreamReader reader) throws XMLStreamException, JMSException {
        ActiveMQTextMessage message = new ActiveMQTextMessage();
        message.setJMSMessageID(idGenerator.generateId());
        QName name = reader.getName();
        String to = getAttributeValue("to", reader);
        String type = getAttributeValue("type",reader);
              
        if (type != null){
            message.setJMSType(type);
        }
              
        if (to != null && to.length() > 0) {
            message.setJMSDestination(createDestination(type,to));
        }
       
        if (this.userName != null && this.userName .length() > 0) {
            message.setJMSReplyTo(createDestination("chat",this.userName));
        }

        while (reader.hasNext()) {
            switch (reader.nextTag()) {
                case XMLStreamConstants.START_ELEMENT:
                    if (!readElement(reader, message)) {
                        log.debug("Unknown element: " + reader.getName());
                    }
                    break;
                case XMLStreamConstants.END_ELEMENT:
                case XMLStreamConstants.END_DOCUMENT:
                    return message;
            }
        }
        return message;
    }

    protected boolean readElement(XMLStreamReader reader, ActiveMQTextMessage message) throws JMSException, XMLStreamException {
        QName name = reader.getName();
        String localPart = name.getLocalPart();
        if (localPart.equals("body")) {
            message.setText(reader.getElementText());
            return true;
        }
        else if (localPart.equals("thread")) {
            message.setJMSCorrelationID(reader.getElementText());
            return true;
        }
        else {
            return false;
        }
    }

    protected String readXMLAsText(XMLStreamReader reader) throws XMLStreamException {
        StringBuffer buffer = new StringBuffer();
        int elementCount = 0;
        while (reader.hasNext()) {
            switch (reader.nextTag()) {
                case XMLStreamConstants.START_ELEMENT:
                    if (elementCount++ > 0) {
                        writeStartElement(reader);
                    }
                    break;

                case XMLStreamConstants.CHARACTERS:
                    buffer.append(reader.getText());
                    break;

                case XMLStreamConstants.END_ELEMENT:
                    if (--elementCount <= 0) {
                        return buffer.toString();
                    }
                    writeEndElement(reader);
                    break;

                case XMLStreamConstants.END_DOCUMENT:
                    return buffer.toString();
            }
        }
        return buffer.toString();
    }

    protected void writeStartElement(XMLStreamReader reader) {
        writer.print("<");
        writeQName(reader.getName());
        for (int i = 0, size = reader.getNamespaceCount(); i < size; i++) {
            writer.print("xmlns");
            String prefix = reader.getNamespacePrefix(i);
            if (prefix != null && prefix.length() > 0) {
                writer.print(":");
                writer.print(prefix);
            }
            writer.print("='");
            writer.print(reader.getNamespaceURI(i));
            writer.print("'");
        }
        for (int i = 0, size = reader.getAttributeCount(); i < size; i++) {
            writer.print("xmlns");
            writeQName(reader.getAttributeName(i));
            writer.print("='");
            writer.print(reader.getAttributeValue(i));
            writer.print("'");
        }
        writer.println(">");
    }

    protected void writeEndElement(XMLStreamReader reader) {
        writer.print("</");
        writeQName(reader.getName());
        writer.println(">");
    }

    protected void writeQName(QName name) {
        String prefix = name.getPrefix();
        if (prefix != null && prefix.length() > 0) {
            writer.print(prefix);
            writer.print(":");
        }
        writer.print(name.getLocalPart());
    }

    protected ActiveMQDestination createDestination(String typeName,String text) {
        int type = ActiveMQDestination.ACTIVEMQ_QUEUE;
        if (text.startsWith(TOPIC_PREFIX)) {
            type = ActiveMQDestination.ACTIVEMQ_TOPIC;
            text = text.substring(TOPIC_PREFIX.length());
        }
        else if (text.startsWith(QUEUE_PREFIX)) {
            type = ActiveMQDestination.ACTIVEMQ_QUEUE;
            text = text.substring(QUEUE_PREFIX.length());
        }
        else if (text.startsWith(TEMP_QUEUE_PREFIX)) {
            type = ActiveMQDestination.ACTIVEMQ_TEMPORARY_QUEUE;
            text = text.substring(TEMP_QUEUE_PREFIX.length());
        }
        else if (text.startsWith(TEMP_TOPIC_PREFIX)) {
            type = ActiveMQDestination.ACTIVEMQ_TEMPORARY_TOPIC;
            text = text.substring(TEMP_TOPIC_PREFIX.length());
        }else {
            if (typeName != null){
                if (typeName.equals("groupchat")){
                    type = ActiveMQDestination.ACTIVEMQ_TOPIC;
                }
                //else default is a queue - (assume default typeName is 'chat')
            }
        }
        text = text.trim();
        if (text.length() == 0) {
            return null;
        }
        return ActiveMQDestination.createDestination(type, text);
    }

    protected String toString(Destination destination) {
        if (destination instanceof ActiveMQDestination) {
            ActiveMQDestination activeDestination = (ActiveMQDestination) destination;
            String physicalName = activeDestination.getPhysicalName();
            switch (activeDestination.getDestinationType()) {
                case ActiveMQDestination.ACTIVEMQ_QUEUE:
                    return QUEUE_PREFIX + physicalName;

                case ActiveMQDestination.ACTIVEMQ_TEMPORARY_QUEUE:
                    return TEMP_QUEUE_PREFIX + physicalName;

                case ActiveMQDestination.ACTIVEMQ_TEMPORARY_TOPIC:
                    return TEMP_TOPIC_PREFIX + physicalName;
            }
            return physicalName;
        }
        return destination != null ? destination.toString() : "";
    }

    protected void writeObjectMessage(ActiveMQObjectMessage message, DataOutput out) throws JMSException, IOException {
        Serializable object = message.getObject();
        String text = (object != null) ? object.toString() : "";
        writeMessage(message, text, out);
    }

    protected void writeTextMessage(ActiveMQTextMessage message, DataOutput out) throws JMSException, IOException {
        writeMessage(message, message.getText(), out);
    }

    protected void writeBytesMessage(ActiveMQBytesMessage message, DataOutput out) throws IOException {
        ByteArray data = message.getBodyAsBytes();
        String text = encodeBinary(data.getBuf(), data.getOffset(), data.getLength());
        writeMessage(message, text, out);
    }

    protected void writeMessage(ActiveMQMessage message, String body, DataOutput out) throws IOException {
        String type = getXmppType(message);

        writer.print("<");
        writer.print(type);
        writer.print(" to='");
        writer.print(toString(message.getJMSDestination()));
        writer.print("' from='");
        writer.print(toString(message.getJMSReplyTo()));
        String messageID = message.getJMSMessageID();
        if (messageID != null) {
            writer.print("' id='");
            writer.print(messageID);
        }

        Map properties = message.getProperties();
        if (properties != null) {
            for (Iterator iter = properties.entrySet().iterator(); iter.hasNext();) {
                Map.Entry entry = (Map.Entry) iter.next();
                Object key = entry.getKey();
                Object value = entry.getValue();
                if (value != null) {
                    writer.print("' ");
                    writer.print(key.toString());
                    writer.print("='");
                    writer.print(value.toString());
                }
            }
        }

        writer.println("'>");

        String id = message.getJMSCorrelationID();
        if (id != null) {
            writer.print("<thread>");
            writer.print(id);
            writer.print("</thread>");
        }
        writer.print("<body>");
        writer.print(body);
        writer.println("</body>");
        writer.print("</");
        writer.print(type);
        writer.println(">");
    }

    protected String encodeBinary(byte[] data, int offset, int length) {
        // TODO
        throw new RuntimeException("Not implemented yet!");
    }

    protected String getXmppType(ActiveMQMessage message) {
        String type = message.getJMSType();
        if (type == null) {
            type = "message";
        }
        return type;
    }
}
TOP

Related Classes of org.activemq.transport.jabber.JabberWireFormat

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.