/**
* 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.camel.component.xmpp;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.apache.camel.Exchange;
import org.apache.camel.impl.DefaultHeaderFilterStrategy;
import org.apache.camel.spi.HeaderFilterStrategy;
import org.apache.camel.util.ObjectHelper;
import org.jivesoftware.smack.packet.DefaultExtensionElement;
import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smackx.jiveproperties.JivePropertiesManager;
import org.jivesoftware.smackx.jiveproperties.packet.JivePropertiesExtension;
import org.jivesoftware.smackx.pubsub.packet.PubSub;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* A Strategy used to convert between a Camel {@link Exchange} and {@link XmppMessage} to and from a
* XMPP {@link Message}
*/
public class XmppBinding {
private static final Logger LOG = LoggerFactory.getLogger(XmppBinding.class);
private HeaderFilterStrategy headerFilterStrategy;
public XmppBinding() {
this.headerFilterStrategy = new DefaultHeaderFilterStrategy();
}
public XmppBinding(HeaderFilterStrategy headerFilterStrategy) {
ObjectHelper.notNull(headerFilterStrategy, "headerFilterStrategy");
this.headerFilterStrategy = headerFilterStrategy;
}
/**
* Populates the given XMPP message from the inbound exchange
*/
public void populateXmppMessage(Message message, Exchange exchange) {
message.setBody(exchange.getIn().getBody(String.class));
Set<Map.Entry<String, Object>> entries = exchange.getIn().getHeaders().entrySet();
for (Map.Entry<String, Object> entry : entries) {
String name = entry.getKey();
Object value = entry.getValue();
if (!headerFilterStrategy.applyFilterToCamelHeaders(name, value, exchange)) {
if ("subject".equalsIgnoreCase(name)) {
// special for subject
String subject = exchange.getContext().getTypeConverter().convertTo(String.class, value);
message.setSubject(subject);
} else if ("language".equalsIgnoreCase(name)) {
// special for language
String language = exchange.getContext().getTypeConverter().convertTo(String.class, value);
message.setLanguage(language);
} else {
try {
JivePropertiesManager.addProperty(message, name, value);
LOG.trace("Added property name: {} value: {}", name, value);
} catch (IllegalArgumentException iae) {
if (LOG.isDebugEnabled()) {
LOG.debug("Cannot add property " + name + " to XMPP message due: ", iae);
}
}
}
}
}
String id = exchange.getExchangeId();
if (id != null) {
JivePropertiesManager.addProperty(message, "exchangeId", id);
}
}
/**
* Populates the given XMPP stanza from the inbound exchange
*/
public void populateXmppStanza(Stanza stanza, Exchange exchange) {
Set<Map.Entry<String, Object>> entries = exchange.getIn().getHeaders().entrySet();
for (Map.Entry<String, Object> entry : entries) {
String name = entry.getKey();
Object value = entry.getValue();
if (!headerFilterStrategy.applyFilterToCamelHeaders(name, value, exchange)) {
try {
JivePropertiesManager.addProperty(stanza, name, value);
LOG.debug("Added property name: " + name + " value: " + value);
} catch (IllegalArgumentException iae) {
LOG.debug("Not adding property " + name + " to XMPP message due to " + iae);
}
}
}
String id = exchange.getExchangeId();
if (id != null) {
JivePropertiesManager.addProperty(stanza, "exchangeId", id);
}
}
/**
* Extracts the body from the XMPP message
*/
public Object extractBodyFromXmpp(Exchange exchange, Stanza stanza) {
return (stanza instanceof Message) ? getMessageBody((Message) stanza) : stanza;
}
private Object getMessageBody(Message message) {
String messageBody = message.getBody();
if (messageBody == null) {
//probably a pubsub message
return message;
}
return messageBody;
}
public Map<String, Object> extractHeadersFromXmpp(Stanza stanza, Exchange exchange) {
Map<String, Object> answer = new HashMap<String, Object>();
ExtensionElement jpe = stanza.getExtension(JivePropertiesExtension.NAMESPACE);
if (jpe != null && jpe instanceof JivePropertiesExtension) {
extractHeadersFrom((JivePropertiesExtension)jpe, exchange, answer);
}
if (jpe != null && jpe instanceof DefaultExtensionElement) {
extractHeadersFrom((DefaultExtensionElement)jpe, exchange, answer);
}
if (stanza instanceof Message) {
Message xmppMessage = (Message) stanza;
answer.put(XmppConstants.MESSAGE_TYPE, xmppMessage.getType());
answer.put(XmppConstants.SUBJECT, xmppMessage.getSubject());
answer.put(XmppConstants.THREAD_ID, xmppMessage.getThread());
} else if (stanza instanceof PubSub) {
PubSub pubsubPacket = (PubSub) stanza;
answer.put(XmppConstants.MESSAGE_TYPE, pubsubPacket.getType());
}
answer.put(XmppConstants.FROM, stanza.getFrom());
answer.put(XmppConstants.PACKET_ID, stanza.getStanzaId());
answer.put(XmppConstants.STANZA_ID, stanza.getStanzaId());
answer.put(XmppConstants.TO, stanza.getTo());
return answer;
}
private void extractHeadersFrom(JivePropertiesExtension jpe, Exchange exchange, Map<String, Object> answer) {
for (String name : jpe.getPropertyNames()) {
Object value = jpe.getProperty(name);
if (!headerFilterStrategy.applyFilterToExternalHeaders(name, value, exchange)) {
answer.put(name, value);
}
}
}
private void extractHeadersFrom(DefaultExtensionElement jpe, Exchange exchange, Map<String, Object> answer) {
for (String name : jpe.getNames()) {
Object value = jpe.getValue(name);
if (!headerFilterStrategy.applyFilterToExternalHeaders(name, value, exchange)) {
answer.put(name, value);
}
}
}
}