/**
* Copyright (c) 2010-2016 by the respective copyright holders.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.openhab.action.xmpp.internal;
import org.apache.commons.lang.ArrayUtils;
import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManagerListener;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Message;
import org.openhab.io.console.Console;
import org.openhab.io.console.ConsoleInterpreter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This console allows to access openHAB remotely through XMPP with
* tools like e.g. GoogleTalk.
* The standard console commands are supported, such as sending item updates,
* commands or querying for items or their current statuses.
* A user must be listed in the configuration in order to be permitted to send
* messages to openHAB.
*
* @author Kai Kreuzer
* @since 0.4.0
*
*/
public class XMPPConsole implements ChatManagerListener, MessageListener {
private static final Logger logger = LoggerFactory.getLogger(XMPPConsole.class);
private String[] allowedUsers;
public XMPPConsole(String[] userArray) {
this.allowedUsers = userArray;
}
@Override
public void chatCreated(Chat chat, boolean arg1) {
String chatUser = chat.getParticipant();
if (chatUser.contains("/")) {
chatUser = chatUser.substring(0, chatUser.indexOf("/"));
}
if (ArrayUtils.contains(allowedUsers, chatUser)) {
chat.addMessageListener(this);
} else {
try {
chat.sendMessage("Sorry, you are not allowed to send messages.");
logger.warn("Received chat request from the unknown user '{}'.", chatUser);
} catch (XMPPException e) {
logger.warn("Error sending XMPP message: {}", e.getMessage());
} catch (NotConnectedException e) {
logger.warn("Error sending XMPP message: {}", e.getMessage());
}
}
}
@Override
public void processMessage(Chat chat, Message msg) {
logger.debug("Received XMPP message: {} of type {}", msg.getBody(), msg.getType());
if (msg.getType() == Message.Type.error || msg.getBody() == null) {
return;
}
String cmd = msg.getBody();
String[] args = cmd.split(" ");
ConsoleInterpreter.handleRequest(args, new ChatConsole(chat));
}
/**
* An implementation of the {@link Console} interface, which sends
* all console output directly to the chat participant.
*
* @author Kai Kreuzer
* @since 0.4.0
*
*/
private static class ChatConsole implements Console {
private Chat chat;
/* used to store strings for simply print commands until a println is sent */
private StringBuffer sb;
public ChatConsole(Chat chat) {
this.chat = chat;
this.sb = new StringBuffer();
}
@Override
public void print(String s) {
sb.append(s);
}
@Override
public void println(String s) {
String msg = sb.toString() + s;
try {
chat.sendMessage(msg);
} catch (XMPPException e) {
logger.error("Error sending message '{}': {}", msg, e.getMessage());
} catch (NotConnectedException e) {
logger.error("Error sending message '{}': {}", msg, e.getMessage());
}
sb = new StringBuffer();
}
@Override
public void printUsage(String s) {
try {
chat.sendMessage("Usage: \n" + s);
} catch (XMPPException e) {
logger.error("Error sending message '{}': {}", s, e.getMessage());
} catch (NotConnectedException e) {
logger.error("Error sending message '{}': {}", s, e.getMessage());
}
}
}
}