001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.camel.component.xmpp;
018
019 import org.apache.camel.Exchange;
020 import org.apache.camel.RuntimeExchangeException;
021 import org.apache.camel.impl.DefaultProducer;
022 import org.jivesoftware.smack.SmackConfiguration;
023 import org.jivesoftware.smack.XMPPConnection;
024 import org.jivesoftware.smack.XMPPException;
025 import org.jivesoftware.smack.packet.Message;
026 import org.jivesoftware.smackx.muc.DiscussionHistory;
027 import org.jivesoftware.smackx.muc.MultiUserChat;
028 import org.slf4j.Logger;
029 import org.slf4j.LoggerFactory;
030
031 /**
032 * @version
033 */
034 public class XmppGroupChatProducer extends DefaultProducer {
035 private static final transient Logger LOG = LoggerFactory.getLogger(XmppGroupChatProducer.class);
036 private final XmppEndpoint endpoint;
037 private XMPPConnection connection;
038 private MultiUserChat chat;
039 private String room;
040
041 public XmppGroupChatProducer(XmppEndpoint endpoint) throws XMPPException {
042 super(endpoint);
043 this.endpoint = endpoint;
044 }
045
046 public void process(Exchange exchange) {
047 Message message = chat.createMessage();
048 message.setTo(room);
049 message.setFrom(endpoint.getUser());
050
051 endpoint.getBinding().populateXmppMessage(message, exchange);
052 try {
053 // make sure we are connected
054 if (!connection.isConnected()) {
055 if (LOG.isDebugEnabled()) {
056 LOG.debug("Reconnecting to: {}", XmppEndpoint.getConnectionMessage(connection));
057 }
058 connection.connect();
059 }
060
061 if (LOG.isDebugEnabled()) {
062 LOG.debug("Sending XMPP message: {}", message.getBody());
063 }
064 chat.sendMessage(message);
065 // must invoke nextMessage to consume the response from the server
066 // otherwise the client local queue will fill up (CAMEL-1467)
067 chat.pollMessage();
068 } catch (XMPPException e) {
069 throw new RuntimeExchangeException("Cannot send XMPP message: " + message, exchange, e);
070 }
071 }
072
073 @Override
074 protected void doStart() throws Exception {
075 if (connection == null) {
076 connection = endpoint.createConnection();
077 }
078
079 if (chat == null) {
080 room = endpoint.resolveRoom(connection);
081 chat = new MultiUserChat(connection, room);
082 DiscussionHistory history = new DiscussionHistory();
083 history.setMaxChars(0); // we do not want any historical messages
084 chat.join(endpoint.getNickname(), null, history, SmackConfiguration.getPacketReplyTimeout());
085 if (LOG.isInfoEnabled()) {
086 LOG.info("Joined room: {} as: {}", room, endpoint.getNickname());
087 }
088 }
089
090 super.doStart();
091 }
092
093 @Override
094 protected void doStop() throws Exception {
095 if (chat != null) {
096 LOG.info("Leaving room: {}", room);
097 chat.leave();
098 }
099 chat = null;
100
101 if (connection != null && connection.isConnected()) {
102 connection.disconnect();
103 }
104 connection = null;
105
106 super.doStop();
107 }
108
109 // Properties
110 // -------------------------------------------------------------------------
111
112 public String getRoom() {
113 return room;
114 }
115
116 }