/*
* Copyright (C) 1999-2006 Jive Software. All rights reserved.
*
* Licensed 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.jivesoftware.openfire.fastpath.settings.chat;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.HashMap;
import java.util.Map;
import org.dom4j.Element;
import org.jivesoftware.database.DbConnectionManager;
import org.jivesoftware.xmpp.workgroup.AgentSession;
import org.jivesoftware.xmpp.workgroup.Workgroup;
import org.jivesoftware.xmpp.workgroup.event.WorkgroupEventDispatcher;
import org.jivesoftware.xmpp.workgroup.event.WorkgroupEventListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xmpp.packet.IQ;
import org.xmpp.packet.PacketError;
/**
* Utility class for doing all Database operations related to the ChatSettings.
* You would use this class to retrieve, update or insert new settings.
*/
public class ChatSettingsManager implements WorkgroupEventListener {
private static final Logger Log = LoggerFactory.getLogger(ChatSettingsManager.class);
private static final String GET_SETTINGS =
"SELECT * FROM fpChatSetting WHERE workgroupNode=?";
private static final String INSERT_CHAT_SETTING =
"INSERT INTO fpChatSetting VALUES(?,?,?,?,?,?,?)";
private static final String UPDATE_CHAT_SETTING =
"UPDATE fpChatSetting SET value=? WHERE name=? AND workgroupNode=?";
private static final String DELETE_CHAT_SETTINGS =
"DELETE FROM fpChatSetting WHERE workgroupNode=?";
private static final String DELETE_SINGLE_CHAT_SETTING =
"DELETE FROM fpChatSetting WHERE name=? AND workgroupNode=?";
private static ChatSettingsManager singleton = new ChatSettingsManager();
/**
* Map for caching settings. This will map by workgroup node.
*/
private final Map<String, ChatSettings> cachedSettings = new HashMap<String, ChatSettings>();
/**
* Returns the singleton instance of <CODE>ChatSettingsManager</CODE>,
* creating it if necessary.
* <p/>
*
* @return the singleton instance of <Code>ChatSettingsManager</CODE>
*/
public static ChatSettingsManager getInstance() {
return singleton;
}
private ChatSettingsManager() {
// Private constructor for singleton design.
WorkgroupEventDispatcher.addListener(this);
}
public static void shutdown() {
WorkgroupEventDispatcher.removeListener(singleton);
singleton = null;
}
/**
* Retrieves the settings for a given workgroup.
*
* @param workgroup the owning workgroup of the settings.
* @return the ChatSettings object mapped to the workgroup.
*/
private ChatSettings getChatSettingsFromDb(Workgroup workgroup) {
final ChatSettings chatSettings = new ChatSettings(workgroup);
cachedSettings.put(workgroup.getJID().getNode(), chatSettings);
Connection con = null;
PreparedStatement pstmt = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(GET_SETTINGS);
String workgroupName = workgroup.getJID().getNode();
pstmt.setString(1, workgroupName);
ResultSet result = pstmt.executeQuery();
if (result.next()) {
do {
//String wg = result.getString("workgroupNode");
int type = result.getInt("type");
String label = result.getString("label");
String description = result.getString("description");
String name = result.getString("name");
String value = result.getString("value");
String defaultValue = result.getString("defaultValue");
ChatSetting setting = new ChatSetting(name);
setting.setWorkgroupNode(workgroupName);
setting.setType(type);
setting.setValue(value);
setting.setDefaultValue(defaultValue);
setting.setLabel(label);
setting.setDescription(description);
chatSettings.addChatSetting(setting);
}
while (result.next());
}
else {
// If no settings were found in the DB then try creating the default settings for
// this workgroup
ChatSettingsCreator.getInstance().createDefaultSettings(workgroup.getJID());
}
}
catch (Exception ex) {
cachedSettings.remove(workgroup.getJID().getNode());
Log.error(ex.getMessage(), ex);
}
finally {
DbConnectionManager.closeConnection(pstmt, con);
}
return chatSettings;
}
/**
* Retrieves the ChatSettings mapped to a particular workgroup.
*
* @param workgroup the owning workgroup of the settings.
* @return the ChatSettings found.
*/
public ChatSettings getChatSettings(Workgroup workgroup) {
String workgroupNode = workgroup.getJID().getNode();
ChatSettings chatSettings = cachedSettings.get(workgroupNode);
if (chatSettings == null) {
synchronized (workgroupNode.intern()) {
chatSettings = cachedSettings.get(workgroupNode);
if (chatSettings == null) {
chatSettings = getChatSettingsFromDb(workgroup);
}
}
}
return chatSettings;
}
/**
* Adds a new ChatSetting, persisting to the database and cache objects.
*
* @param settings the <code>ChatSetting</code> to add.
*/
public void addChatSetting(ChatSetting settings) {
Connection con;
PreparedStatement pstmt = null;
try {
con = DbConnectionManager.getConnection();
try {
pstmt = con.prepareStatement(INSERT_CHAT_SETTING);
pstmt.setString(1, settings.getWorkgroupNode());
pstmt.setInt(2, settings.getType().getType());
pstmt.setString(3, settings.getLabel());
pstmt.setString(4, settings.getDescription());
pstmt.setString(5, settings.getKey().toString());
DbConnectionManager.setLargeTextField(pstmt, 6, settings.getValue());
pstmt.setString(7, settings.getDefaultValue());
pstmt.executeUpdate();
}
catch (Exception ex) {
Log.error(ex.getMessage(), ex);
}
finally {
DbConnectionManager.closeConnection(pstmt, con);
}
}
catch (Exception ex) {
Log.error(ex.getMessage(), ex);
}
// Add to cache
ChatSettings chatSettings = cachedSettings.get(settings.getWorkgroupNode());
if (chatSettings != null) {
chatSettings.addChatSetting(settings);
}
}
/**
* Update a WebChatSetting in the Database.
*
* @param settings the <code>WebChatSetting</code> to update.
*/
public void updateChatSetting(ChatSetting settings) {
Connection con;
PreparedStatement pstmt = null;
try {
con = DbConnectionManager.getConnection();
try {
pstmt = con.prepareStatement(UPDATE_CHAT_SETTING);
DbConnectionManager.setLargeTextField(pstmt, 1, settings.getValue());
pstmt.setString(2, settings.getKey().toString());
pstmt.setString(3, settings.getWorkgroupNode());
pstmt.executeUpdate();
}
catch (Exception ex) {
Log.error(ex.getMessage(), ex);
}
finally {
DbConnectionManager.closeConnection(pstmt, con);
}
}
catch (Exception ex) {
Log.error(ex.getMessage(), ex);
}
// Add to cache
ChatSettings chatSettings = cachedSettings.get(settings.getWorkgroupNode());
if (chatSettings != null) {
chatSettings.addChatSetting(settings);
}
}
/**
* Removes a <code>WebChatSetting</code> from the database.
*
* @param setting the WebChatSetting to remove.
*/
public void removeChatSetting(ChatSetting setting) {
Connection con;
PreparedStatement pstmt = null;
try {
con = DbConnectionManager.getConnection();
try {
pstmt = con.prepareStatement(DELETE_SINGLE_CHAT_SETTING);
pstmt.setString(1, setting.getKey().toString());
pstmt.setString(2, setting.getWorkgroupNode());
pstmt.executeUpdate();
}
catch (Exception ex) {
Log.error(ex.getMessage(), ex);
}
finally {
DbConnectionManager.closeConnection(pstmt, con);
}
}
catch (Exception ex) {
Log.error(ex.getMessage(), ex);
}
// Add to cache
ChatSettings chatSettings = cachedSettings.get(setting.getWorkgroupNode());
if (chatSettings != null) {
chatSettings.removeChatSetting(setting);
}
}
/**
* Removes a <code>WebChatSetting</code> from the database.
*
* @param key the key of the chat setting to remove.
* @param workgroup the workgroup the key belongs to.
*/
public void removeChatSetting(KeyEnum key, Workgroup workgroup) {
String workgroupNode = workgroup.getJID().getNode();
Connection con;
PreparedStatement pstmt = null;
try {
con = DbConnectionManager.getConnection();
try {
pstmt = con.prepareStatement(DELETE_SINGLE_CHAT_SETTING);
pstmt.setString(1, key.toString());
pstmt.setString(2, workgroupNode);
pstmt.executeUpdate();
}
catch (Exception ex) {
Log.error(ex.getMessage(), ex);
}
finally {
DbConnectionManager.closeConnection(pstmt, con);
}
}
catch (Exception ex) {
Log.error(ex.getMessage(), ex);
}
// Add to cache
ChatSettings chatSettings = cachedSettings.get(workgroupNode);
if (chatSettings != null) {
ChatSetting setting = chatSettings.getChatSetting(key);
if (setting != null) {
chatSettings.removeChatSetting(setting);
}
}
}
/**
* Retrieves a <code>WebChatSetting</code> based on the owning workgroup and setting key.
*
* @param workgroup the owning workgroup.
* @param key the setting key to find.
* @return the ChatSetting found, otherwise null is returned.
*/
public ChatSetting getChatSetting(Workgroup workgroup, String key) {
ChatSettings chatSettings = getChatSettings(workgroup);
if (chatSettings != null) {
return chatSettings.getChatSetting(key);
}
return null;
}
/**
* Send all WebChat settings for a particular Workgroup.
*
* @param packet the original packet that made the request.
* @param workgroup the workgroup the packet was sent to.
*/
public void getAllChatSettings(IQ packet, Workgroup workgroup) {
IQ reply = IQ.createResultIQ(packet);
// Retrieve the web chat setting.
ChatSettings chatSettings = getChatSettings(workgroup);
if (chatSettings == null) {
reply.setChildElement(packet.getChildElement().createCopy());
reply.setError(new PacketError(PacketError.Condition.item_not_found));
workgroup.send(reply);
return;
}
Element webSettings = reply.setChildElement("chat-settings", "http://jivesoftware.com/protocol/workgroup");
for (ChatSetting setting : chatSettings.getChatSettings()) {
Element root = webSettings.addElement("chat-setting");
try {
root.addElement("key").setText(setting.getKey().toString());
root.addElement("value").setText(setting.getValue());
root.addElement("type").setText(Integer.toString(setting.getType().getType()));
}
catch (Exception e) {
Log.error(e.getMessage(), e);
}
}
workgroup.send(reply);
}
/**
* Send all WebChat settings for a particular Workgroup and type.
*
* @param packet the original packet that made the request.
* @param workgroup the workgroup the packet was sent to.
* @param type the type.
*/
public void getChatSettingsByType(IQ packet, Workgroup workgroup, int type) {
IQ reply = IQ.createResultIQ(packet);
// Retrieve the web chat setting.
ChatSettings chatSettings = getChatSettings(workgroup);
if (chatSettings == null) {
reply.setChildElement(packet.getChildElement().createCopy());
reply.setError(new PacketError(PacketError.Condition.item_not_found));
workgroup.send(reply);
return;
}
Element webSettings = reply.setChildElement("chat-settings", "http://jivesoftware.com/protocol/workgroup");
for (ChatSetting setting : chatSettings.getChatSettings()) {
if (setting.getType().getType() == type) {
Element root = webSettings.addElement("chat-setting");
root.addElement("key").setText(setting.getKey().toString());
root.addElement("value").setText(setting.getValue());
root.addElement("type").setText(Integer.toString(setting.getType().getType()));
}
}
workgroup.send(reply);
}
/**
* Send a single WebChat setting a given workgroup.
*
* @param packet the original packet that made the request.
* @param workgroup the workgroup the packet was sent to.
* @param key the mapped setting key.
*/
public void getChatSettingByKey(IQ packet, Workgroup workgroup, String key) {
IQ reply = IQ.createResultIQ(packet);
// Retrieve the web chat setting.
ChatSetting setting = getChatSetting(workgroup, key);
if (setting == null) {
reply.setChildElement(packet.getChildElement().createCopy());
reply.setError(new PacketError(PacketError.Condition.item_not_found));
workgroup.send(reply);
return;
}
Element webSettings = reply.setChildElement("chat-settings", "http://jivesoftware.com/protocol/workgroup");
Element root = webSettings.addElement("chat-setting");
root.addElement("key").setText(setting.getKey().toString());
root.addElement("value").setText(setting.getValue());
root.addElement("type").setText(Integer.toString(setting.getType().getType()));
workgroup.send(reply);
}
public void workgroupCreated(Workgroup workgroup) {
}
public void workgroupDeleting(Workgroup workgroup) {
}
public void workgroupDeleted(Workgroup workgroup) {
String workgroupNode = workgroup.getJID().getNode();
// Remove settings from cache
cachedSettings.remove(workgroupNode);
// Delete from DB.
Connection con;
PreparedStatement pstmt = null;
try {
con = DbConnectionManager.getConnection();
try {
pstmt = con.prepareStatement(DELETE_CHAT_SETTINGS);
pstmt.setString(1, workgroupNode);
pstmt.executeUpdate();
}
catch (Exception ex) {
Log.error(ex.getMessage(), ex);
}
finally {
DbConnectionManager.closeConnection(pstmt, con);
}
}
catch (Exception ex) {
Log.error(ex.getMessage(), ex);
}
}
public void workgroupOpened(Workgroup workgroup) {
}
public void workgroupClosed(Workgroup workgroup) {
}
public void agentJoined(Workgroup workgroup, AgentSession agentSession) {
}
public void agentDeparted(Workgroup workgroup, AgentSession agentSession) {
}
public void chatSupportStarted(Workgroup workgroup, String sessionID) {
}
public void chatSupportFinished(Workgroup workgroup, String sessionID) {
}
public void agentJoinedChatSupport(Workgroup workgroup, String sessionID, AgentSession agentSession) {
}
public void agentLeftChatSupport(Workgroup workgroup, String sessionID, AgentSession agentSession) {
}
}