/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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.apache.vysper.xmpp.writer; import java.util.Iterator; import java.util.List; import org.apache.vysper.xml.fragment.XMLElement; import org.apache.vysper.xml.fragment.XMLSemanticError; import org.apache.vysper.xml.fragment.XMLText; import org.apache.vysper.xmpp.stanza.IQStanza; import org.apache.vysper.xmpp.stanza.Stanza; import org.apache.vysper.xmpp.stanza.XMPPCoreStanza; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * renders only reduced digest stanza information for logging output * * @author The Apache MINA Project (dev@mina.apache.org) */ public class DenseStanzaLogRenderer { final static Logger logger = LoggerFactory.getLogger(DenseStanzaLogRenderer.class); private static final String ELEMENT_SEPARATOR = "."; private static final String ATTR_QUOTE = "'"; private static final String EQUALS = "="; public static String render(XMLElement stanza) { try { StringBuilder stringBuilder = new StringBuilder(); if (stanza == null) return stringBuilder.append("NULL_STANZA").toString(); String outerName = stanza.getName(); stringBuilder.append(outerName); XMLElement firstInnerElement = stanza.getFirstInnerElement(); if ("stream".equals(outerName)) { renderStreamStart(stringBuilder, stanza, firstInnerElement); } else if ("message".equals(outerName)) { renderMessage(stringBuilder, stanza, firstInnerElement); } else if ("error".equals(outerName)) { renderError(stringBuilder, stanza, firstInnerElement); } else if ("presence".equals(outerName)) { renderPresence(stringBuilder, stanza, firstInnerElement); } else if ("auth".equals(outerName)) { renderAuth(stringBuilder, stanza, firstInnerElement); } else if ("iq".equals(outerName)) { renderIQ(stringBuilder, stanza, firstInnerElement); } return stringBuilder.toString(); } catch (Exception e) { logger.warn("error when rendering stanza {}: {}", stanza.toString(), e); return "*render-exception*"; } } private static void renderIQ(StringBuilder stringBuilder, XMLElement stanza, XMLElement firstInnerElement) { IQStanza iq = (IQStanza) XMPPCoreStanza.getWrapper((Stanza) stanza); renderAttribute(stringBuilder, iq, "id"); renderAttribute(stringBuilder, iq, "to"); renderAttribute(stringBuilder, iq, "from"); renderAttribute(stringBuilder, iq, "type"); if (firstInnerElement != null) { stringBuilder.append(ELEMENT_SEPARATOR).append(firstInnerElement.getName()); if ("query".equals(firstInnerElement.getName())) { renderIQQuery(stringBuilder, firstInnerElement); } else { renderNamespace(stringBuilder, firstInnerElement); } } } private static void renderIQQuery(StringBuilder stringBuilder, XMLElement queryElement) { String nsUri = queryElement.getNamespaceURI(); if (nsUri == null) { stringBuilder.append(ELEMENT_SEPARATOR).append("?").append("xmlns").append("?"); return; } if (!nsUri.startsWith("http://jabber.org/protocol/disco")) { renderNamespace(stringBuilder, queryElement); return; } stringBuilder.append(ELEMENT_SEPARATOR).append("disco"); if (nsUri.equals("http://jabber.org/protocol/disco#items")) { stringBuilder.append(ELEMENT_SEPARATOR).append("items"); } else if (nsUri.equals("http://jabber.org/protocol/disco#info")) { stringBuilder.append(ELEMENT_SEPARATOR).append("info"); List<XMLElement> features = queryElement.getInnerElementsNamed("feature"); if (features != null) for (XMLElement feature : features) { String varAttrValue = feature.getAttributeValue("var"); if (varAttrValue == null) varAttrValue = "NOT_GIVEN"; renderAttributeForm(stringBuilder, "feature", varAttrValue); } } else { stringBuilder.append(ELEMENT_SEPARATOR).append("????"); } // TODO render inner elements in case of result etc. } private static void renderAuth(StringBuilder stringBuilder, XMLElement stanza, XMLElement firstInnerElement) { renderAttribute(stringBuilder, stanza, "mechanism"); } private static void renderStreamStart(StringBuilder stringBuilder, XMLElement stanza, XMLElement firstInnerElement) { try { XMLElement features = stanza.getSingleInnerElementsNamed("features"); if (features != null) { XMLElement starttls = features.getSingleInnerElementsNamed("starttls"); if (starttls != null) { stringBuilder.append(ELEMENT_SEPARATOR); stringBuilder.append("starttls"); XMLElement required = starttls.getSingleInnerElementsNamed("required"); if (required != null) stringBuilder.append("[required]"); } XMLElement mechanisms = features.getSingleInnerElementsNamed("mechanisms"); if (mechanisms != null) { stringBuilder.append(ELEMENT_SEPARATOR); stringBuilder.append("features.mechanisms["); List<XMLElement> list = mechanisms.getInnerElementsNamed("mechanism"); if (list != null) { for (Iterator<XMLElement> it = list.iterator(); it.hasNext();) { XMLElement element = it.next(); stringBuilder.append(element.getSingleInnerText().getText()); if (it.hasNext()) stringBuilder.append(","); } } stringBuilder.append("]"); } } } catch (XMLSemanticError xmlSemanticError) { stringBuilder.append("*error*"); } } private static void renderError(StringBuilder stringBuilder, XMLElement stanza, XMLElement firstInnerElement) { if (firstInnerElement == null) { stringBuilder.append(ELEMENT_SEPARATOR); stringBuilder.append("???"); return; } stringBuilder.append(ELEMENT_SEPARATOR); stringBuilder.append(firstInnerElement.getName()); } private static void renderPresence(StringBuilder stringBuilder, XMLElement stanza, XMLElement firstInnerElement) { renderAttribute(stringBuilder, stanza, "type"); renderAttribute(stringBuilder, stanza, "from"); renderAttribute(stringBuilder, stanza, "to"); try { XMLElement show = stanza.getSingleInnerElementsNamed("show"); if (show != null) { XMLText showText = show.getSingleInnerText(); if (showText != null) { stringBuilder.append(ELEMENT_SEPARATOR); stringBuilder.append("show").append(EQUALS); stringBuilder.append(ATTR_QUOTE).append(showText).append(ATTR_QUOTE); } } XMLElement status = stanza.getSingleInnerElementsNamed("status"); if (status != null) { XMLText statusText = status.getSingleInnerText(); if (statusText != null) { stringBuilder.append(ELEMENT_SEPARATOR); stringBuilder.append("status").append(EQUALS); stringBuilder.append(ATTR_QUOTE).append(statusText).append(ATTR_QUOTE); } } XMLElement caps = stanza.getSingleInnerElementsNamed("c"); if (caps != null) { renderAttribute(stringBuilder, caps, "node"); renderAttribute(stringBuilder, caps, "ver"); renderAttribute(stringBuilder, caps, "ext"); } } catch (XMLSemanticError xmlSemanticError) { stringBuilder.append("*error*"); } } private static void renderNamespace(StringBuilder stringBuilder, XMLElement element) { String ns = element.getNamespaceURI(); if (ns != null) { renderAttributeForm(stringBuilder, "xmlns", ns); } } private static void renderAttribute(StringBuilder stringBuilder, XMLElement element, String attributeName) { String attributeValue = element.getAttributeValue(attributeName); if (attributeValue != null) { renderAttributeForm(stringBuilder, attributeName, attributeValue); } } private static void renderAttributeForm(StringBuilder stringBuilder, String attributeName, String value) { stringBuilder.append(ELEMENT_SEPARATOR); stringBuilder.append(attributeName).append(EQUALS); stringBuilder.append(ATTR_QUOTE).append(value).append(ATTR_QUOTE); } private static void renderMessage(StringBuilder stringBuilder, XMLElement stanza, XMLElement firstInnerElement) { if (firstInnerElement != null) { stringBuilder.append(ELEMENT_SEPARATOR); stringBuilder.append(firstInnerElement.getName()); String firstInnerName = firstInnerElement.getName(); if ("body".equals(firstInnerName)) { stringBuilder.append(ELEMENT_SEPARATOR); XMLText xmlText = null; try { xmlText = firstInnerElement.getSingleInnerText(); if (xmlText != null) stringBuilder.append(xmlText.getText()); } catch (XMLSemanticError xmlSemanticError) { stringBuilder.append("???"); } } } } }