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.apache.commons.logging.Log;
023 import org.apache.commons.logging.LogFactory;
024 import org.jivesoftware.smack.SmackConfiguration;
025 import org.jivesoftware.smack.XMPPConnection;
026 import org.jivesoftware.smack.XMPPException;
027 import org.jivesoftware.smack.packet.Message;
028 import org.jivesoftware.smackx.muc.DiscussionHistory;
029 import org.jivesoftware.smackx.muc.MultiUserChat;
030
031 /**
032 * @version $Revision: 756358 $
033 */
034 public class XmppGroupChatProducer extends DefaultProducer {
035 private static final transient Log LOG = LogFactory.getLog(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.nextMessage();
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: " + room + " as: " + endpoint.getNickname());
087 }
088 }
089
090 super.doStart();
091 }
092
093 @Override
094 protected void doStop() throws Exception {
095 if (chat != null) {
096 if (LOG.isInfoEnabled()) {
097 LOG.info("Leaving room: " + room);
098 }
099 chat.leave();
100 chat = null;
101 }
102 if (connection != null) {
103 if (LOG.isDebugEnabled()) {
104 LOG.debug("Disconnecting from: " + XmppEndpoint.getConnectionMessage(connection));
105 }
106 connection.disconnect();
107 connection = null;
108 }
109 super.doStop();
110 }
111
112 // Properties
113 // -------------------------------------------------------------------------
114
115 public String getRoom() {
116 return room;
117 }
118
119 }