/* * 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) { } }