Java tutorial
/* * Copyright 2018-present Open Networking Foundation * * 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.onosproject.xmpp.core.ctl.handlers; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.MessageToMessageDecoder; import org.dom4j.DocumentFactory; import org.dom4j.Element; import org.dom4j.QName; import org.onosproject.xmpp.core.XmppConstants; import org.onosproject.xmpp.core.ctl.XmppValidator; import org.onosproject.xmpp.core.ctl.exception.UnsupportedStanzaTypeException; import org.onosproject.xmpp.core.ctl.exception.XmppValidationException; import org.onosproject.xmpp.core.stream.XmppStreamClose; import org.onosproject.xmpp.core.stream.XmppStreamError; import org.onosproject.xmpp.core.stream.XmppStreamOpen; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xmpp.packet.IQ; import org.xmpp.packet.Message; import org.xmpp.packet.Packet; import org.xmpp.packet.Presence; import javax.xml.stream.events.Attribute; import javax.xml.stream.events.Namespace; import javax.xml.stream.events.StartElement; import javax.xml.stream.events.XMLEvent; import java.util.Iterator; import java.util.List; import static com.google.common.base.Preconditions.checkNotNull; /** * Translates XML Element to XMPP Packet. */ public class XmppDecoder extends MessageToMessageDecoder { private final Logger logger = LoggerFactory.getLogger(getClass()); private XmppValidator validator = new XmppValidator(); @Override protected void decode(ChannelHandlerContext channelHandlerContext, Object object, List out) throws Exception { if (object instanceof Element) { Element root = (Element) object; try { Packet packet = recognizeAndReturnXmppPacket(root); validate(packet); out.add(packet); } catch (UnsupportedStanzaTypeException e) { throw e; } catch (Exception e) { throw new XmppValidationException(false); } } else if (object instanceof XMLEvent) { XMLEvent event = (XMLEvent) object; if (event.isStartElement()) { final StartElement element = event.asStartElement(); if (element.getName().getLocalPart().equals(XmppConstants.STREAM_QNAME)) { DocumentFactory df = DocumentFactory.getInstance(); QName qname = (element.getName().getPrefix() == null) ? df.createQName(element.getName().getLocalPart(), element.getName().getNamespaceURI()) : df.createQName(element.getName().getLocalPart(), element.getName().getPrefix(), element.getName().getNamespaceURI()); Element newElement = df.createElement(qname); Iterator nsIt = element.getNamespaces(); // add all relevant XML namespaces to Element while (nsIt.hasNext()) { Namespace ns = (Namespace) nsIt.next(); newElement.addNamespace(ns.getPrefix(), ns.getNamespaceURI()); } Iterator attrIt = element.getAttributes(); // add all attributes to Element while (attrIt.hasNext()) { Attribute attr = (Attribute) attrIt.next(); newElement.addAttribute(attr.getName().getLocalPart(), attr.getValue()); } XmppStreamOpen xmppStreamOpen = new XmppStreamOpen(newElement); validator.validateStream(xmppStreamOpen); out.add(xmppStreamOpen); } } else if (event.isEndElement()) { out.add(new XmppStreamClose()); } } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { logger.info("Exception caught: {}", cause.getMessage()); if (cause.getCause() instanceof XmppValidationException) { if (((XmppValidationException) cause.getCause()).isStreamValidationException()) { XmppStreamError.Condition condition = XmppStreamError.Condition.bad_format; XmppStreamError error = new XmppStreamError(condition); ctx.channel().writeAndFlush(error); ctx.channel().writeAndFlush(new XmppStreamClose()); return; } } logger.info("Not a StreamValidationException. Sending exception upstream."); ctx.fireExceptionCaught(cause); } private void validate(Packet packet) throws UnsupportedStanzaTypeException, XmppValidationException { validator.validate(packet); } protected Packet recognizeAndReturnXmppPacket(Element root) throws UnsupportedStanzaTypeException, IllegalArgumentException { checkNotNull(root); Packet packet = null; if (root.getName().equals(XmppConstants.IQ_QNAME)) { packet = new IQ(root); } else if (root.getName().equals(XmppConstants.MESSAGE_QNAME)) { packet = new Message(root); } else if (root.getName().equals(XmppConstants.PRESENCE_QNAME)) { packet = new Presence(root); } else { throw new UnsupportedStanzaTypeException("Unrecognized XMPP Packet"); } logger.info("XMPP Packet received\n" + root.asXML()); return packet; } }