最近一段时间因为工作关系,可能会整理一些spark二次开发的细节问题。
客户端工具栏,可以在客户端上添加各种系统的集成,一些小功能实现的快捷方式。
具体修改类为workspace.java
具体代码如下:
* $RCSfile: ,v $
package org.jivesoftware.spark;
import java.awt.BorderLayout;
/**
* The inner Container for Spark. The Workspace is the container for all plugins
* into the Spark install. Plugins would use this for the following:
* <p/>
* <ul>
* <li>Add own tab to the main tabbed pane. ex.
* <p/>
* <p/>
* Workspace workspace = SparkManager.getWorkspace(); JButton button = new
* JButton("HELLO SPARK USERS"); workspace.getWorkspacePane().addTab("MyPlugin",
* button);
* </p>
* <p/>
* <li>Retrieve the ContactList. description: 即时通讯面板空间
*
* @author e40
* @project_name Lyim
* @version v1.0
* @createTime 2011-6-1 下午03:36:21
*/
public class Workspace extends JPanel implements PacketListener {
private static final long serialVersionUID = 7076407890063933765L;
private SparkTabbedPane workspacePane;
private StatusBar statusBox;
private CommandPanel toolPanel; // 扩展工具栏
private ContactList contactList;
private ConferenceServices conferences;
private GatewayPlugin gatewayPlugin;
private BookmarkPlugin bookmarkPlugin;
private ChatTranscriptPlugin transcriptPlugin;
private BroadcastPlugin broadcastPlugin;
private ScratchPadPlugin scratchPadPlugin;
private static Workspace singleton;
private static final Object LOCK = new Object();
private JPanel cardPanel;
private CardLayout cardLayout;
public static final String WORKSPACE_PANE = "WORKSPACE_PANE";
private final RolloverButton message_btn;
private final RolloverButton loginPortal_btn;
private final RolloverButton openLyimBrowser_btn;
private RolloverButton mail_btn=new RolloverButton(
SparkRes.getImageIcon(SparkRes.MESSAGE_NOTICE_IMAGE));;
private final RolloverButton broadcast_btn;
private final RolloverButton task_btn;
private String mail_CallbackStr = "";
private static boolean alert_msg = true;
private final RolloverButton notes_btn = new RolloverButton(
SparkRes.getImageIcon(SparkRes.DOCUMENT_16x16));
/**
* Returns the singleton instance of <CODE>Workspace</CODE>, creating it if
* necessary.
* <p/>
*
* @return the singleton instance of <Code>Workspace</CODE>
*/
public static Workspace getInstance() {
// Synchronize on LOCK to ensure that we don't end up creating
// two singletons.
synchronized (LOCK) {
if (null == singleton) {
Workspace controller = new Workspace();
singleton = controller;
return controller;
}
}
return singleton;
}
/**
* Creates the instance of the SupportChatWorkspace.
*/
private Workspace() {
final MainWindow mainWindow = SparkManager.getMainWindow();
// Add MainWindow listener
mainWindow.addMainWindowListener(new MainWindowListener() {
public void shutdown() {
final ChatContainer container = SparkManager.getChatManager()
.getChatContainer();
// Close all Chats.
for (ChatRoom chatRoom : container.getChatRooms()) {
// Leave ChatRoom
container.leaveChatRoom(chatRoom);
}
conferences.shutdown();
gatewayPlugin.shutdown();
bookmarkPlugin.shutdown();
broadcastPlugin.shutdown();
}
public void mainWindowActivated() {
}
public void mainWindowDeactivated() {
}
});
// Initialize workspace pane, defaulting the tabs to the bottom.
workspacePane = new SparkTabbedPane(JTabbedPane.BOTTOM);
workspacePane.setBorder(BorderFactory.createEmptyBorder());
// Add Panels.
cardLayout = new CardLayout();
cardPanel = new JPanel(cardLayout);
cardPanel.setOpaque(false);
cardPanel.add(WORKSPACE_PANE, this);
statusBox = new StatusBar();
toolPanel = new CommandPanel();
if(!Default.getBoolean("MAIL_DISABLE")){
mail_CallbackStr = MailUtils.getCallbackStr();
if (mail_CallbackStr.equals("?") && alert_msg) {
alert_msg = false;
int key = JOptionPane.showConfirmDialog(this, "邮箱绑定错误,是否重新绑定?",
"邮箱错误", JOptionPane.OK_CANCEL_OPTION);
if (key == JOptionPane.OK_OPTION) {
try {
BrowserLauncher.openSystem(SparkRes
.getString(SparkRes.MAIL_URL));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
mail_btn = new RolloverButton(
SparkRes.getImageIcon(SparkRes.MESSAGE_NOTICE_IMAGE));
mail_btn.setToolTipText("绑定邮箱错误");
} else if (mail_CallbackStr.equals("No_Buddy") && alert_msg) {
alert_msg = false;
int reply = JOptionPane.showConfirmDialog(this, "未绑定邮箱,请先到门户绑定邮箱",
"绑定邮箱", JOptionPane.OK_CANCEL_OPTION);
if (reply == JOptionPane.OK_OPTION) {
try {
BrowserLauncher.openSystem(SparkRes
.getString(SparkRes.MAIL_URL));
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
mail_btn = new RolloverButton(
SparkRes.getImageIcon(SparkRes.MESSAGE_NOTICE_IMAGE));
mail_btn.setToolTipText("未绑定邮箱");
} else if (mail_CallbackStr.equals("error") && alert_msg) {
alert_msg = false;
JOptionPane.showMessageDialog(this, "邮件服务器配置错误!", "邮箱错误", JOptionPane.CLOSED_OPTION);
mail_btn = new RolloverButton(
SparkRes.getImageIcon(SparkRes.MESSAGE_NOTICE_IMAGE));
mail_btn.setToolTipText("邮件服务器配置错误");
} else {
mail_btn = new RolloverButton(mail_CallbackStr,
SparkRes.getImageIcon(SparkRes.MESSAGE_NOTICE_IMAGE));
mail_btn.setToolTipText("未读邮件:" + mail_CallbackStr);
}
//如果要屏蔽邮件,此处需修改
// toolPanel.add(mail_btn);
mail_btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
BrowserLauncher.openSystem(SparkRes
.getString(SparkRes.MAIL_URL));
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
}
message_btn = new RolloverButton(
SparkRes.getImageIcon(SparkRes.MESSAGE_BOX_IMAGE));
loginPortal_btn = new RolloverButton(
SparkRes.getImageIcon(SparkRes.PORTAL_LOGIN_IMAGE));
openLyimBrowser_btn = new RolloverButton(
SparkRes.getImageIcon(SparkRes.MESSAGE_VIEW_IMAGE));
broadcast_btn = new RolloverButton(
SparkRes.getImageIcon(SparkRes.MEGAPHONE_16x16));
task_btn = new RolloverButton(
SparkRes.getImageIcon(SparkRes.DESKTOP_IMAGE));
toolPanel.add(loginPortal_btn);
//如果不配置邮件,此处需修改
// toolPanel.add(mail_btn);
if (!Default.getBoolean("BROWSER_DISABLE")) {
toolPanel.add(openLyimBrowser_btn);
}
toolPanel.add(broadcast_btn);
toolPanel.add(message_btn);
toolPanel.add(task_btn);
toolPanel.add(notes_btn);
loginPortal_btn.setToolTipText("登录门户系统");
message_btn.setToolTipText("查看消息公告");
openLyimBrowser_btn.setToolTipText("我的资讯");
broadcast_btn.setToolTipText("广播消息");
task_btn.setToolTipText("查看任务列表");
notes_btn.setToolTipText("查看记事本");
task_btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
scratchPadPlugin.getTask();
}
});
notes_btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
scratchPadPlugin.getNotes();
}
});
// duanwu by hc
loginPortal_btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
String url = SparkRes.getString(SparkRes.TARGET_URL);
BrowserLauncher.openSystem(url);
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
message_btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
new MessageBox().invokeDialog();
}
});
broadcast_btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
broadcastToRoster();
}
private void broadcastToRoster() {
final BroadcastDialog broadcastDialog = new BroadcastDialog();
broadcastDialog.invokeDialog();
}
});
openLyimBrowser_btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
EmbeddedBrowserViewer viewer = new EmbeddedBrowserViewer();
viewer.initializeBrowser();
JFrame frame = new JFrame();
frame.setFont(new Font("微软雅黑", Font.PLAIN, 13));
frame.setIconImage(SparkRes.getImageIcon(
SparkRes.MESSAGE_VIEW_IMAGE).getImage());
frame.getContentPane().setLayout(new BorderLayout());
frame.getContentPane().add(viewer, BorderLayout.CENTER);
frame.setVisible(true);
frame.pack();
frame.setSize(600, 400);
// final ClassLoader cl = SparkRes.class.getClassLoader();
// viewer.loadURL(cl.getResource("web/package.html").toString());
String default_infor_url = Default
.getString(Default.MY_INFORMATION);
viewer.loadURL(default_infor_url);
frame.setResizable(false);
}
});
// final TimerTask task = new SwingTimerTask() {
// public void doRun() {
// String mail_CallbackStr = "0";
// mail_CallbackStr = MailUtils.getCallbackStr();
//
// mail_btn.setText(mail_CallbackStr + "");
// if (mail_CallbackStr.equals("error")) {
// mail_btn.setToolTipText("邮件服务器配置错误");
// } else if (mail_CallbackStr.equals("error")) {
// mail_btn.setToolTipText("邮件绑定错误");
// } else {
// mail_btn.setText(mail_CallbackStr);
// mail_btn.setToolTipText("未读邮件数:" + mail_CallbackStr);
// }
// }
// };
// TaskEngine.getInstance()
// .schedule(
// task,
// Integer.parseInt(Default
// .getString(Default.DEFAULT_EMAIL_TIME)) * 1000);
// Build default workspace
this.setLayout(new GridBagLayout());
add(workspacePane, new GridBagConstraints(0, 9, 1, 1, 1.0, 1.0,
GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(0,
0, 0, 0), 0, 0));
add(statusBox, new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0,
GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
new Insets(0, 0, 0, 0), 0, 0));
add(toolPanel, new GridBagConstraints(0, 1, 1, 1, 1.0, 0.0,
GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(1,
0, 1, 0), 0, 0));
this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
KeyStroke.getKeyStroke("F12"), "showDebugger");
this.getActionMap().put("showDebugger",
new AbstractAction("showDebugger") {
private static final long serialVersionUID = 4066886679016416923L;
public void actionPerformed(ActionEvent evt) {
EnhancedDebuggerWindow window = EnhancedDebuggerWindow
.getInstance();
window.setVisible(true);
}
});
// Set background
setBackground(new Color(235, 239, 254));
}
/**
* Builds the Workspace layout.
*/
public void buildLayout() {
new Enterprise();
// Initialize Contact List
contactList = new ContactList();
conferences = new ConferenceServices();
// Init contact list.
contactList.initialize();
// Load VCard information for status box
statusBox.loadVCard();
// Initialise TransferManager
SparkTransferManager.getInstance();
}
/**
* Starts the Loading of all Spark Plugins.
*/
public void loadPlugins() {
// Add presence and message listeners
// we listen for these to force open a 1-1 peer chat window from other
// operators if
// one isn't already open
PacketFilter workspaceMessageFilter = new PacketTypeFilter(
Message.class);
// Add the packetListener to this instance
SparkManager.getSessionManager().getConnection()
.addPacketListener(this, workspaceMessageFilter);
// Make presence available to anonymous requests, if from anonymous user
// in the system.
PacketListener workspacePresenceListener = new PacketListener() {
public void processPacket(Packet packet) {
Presence presence = (Presence) packet;
if (presence.getProperty("anonymous") != null) {
boolean isAvailable = statusBox.getPresence().getMode() == Presence.Mode.available;
Presence reply = new Presence(Presence.Type.available);
if (!isAvailable) {
reply.setType(Presence.Type.unavailable);
}
reply.setTo(presence.getFrom());
SparkManager.getSessionManager().getConnection()
.sendPacket(reply);
}
}
};
SparkManager
.getSessionManager()
.getConnection()
.addPacketListener(workspacePresenceListener,
new PacketTypeFilter(Presence.class));
// Send Available status
final Presence presence = SparkManager.getWorkspace().getStatusBar()
.getPresence();
SparkManager.getSessionManager().changePresence(presence);
// Until we have better plugin management, will init after presence
// updates.
gatewayPlugin = new GatewayPlugin();
gatewayPlugin.initialize();
// Load all non-presence related items.
conferences.loadConferenceBookmarks();
SearchManager.getInstance();
transcriptPlugin = new ChatTranscriptPlugin();
// Load Broadcast Plugin
broadcastPlugin = new BroadcastPlugin();
broadcastPlugin.initialize();
// Load BookmarkPlugin
bookmarkPlugin = new BookmarkPlugin();
bookmarkPlugin.initialize();
// Load scratchPadPlugin
scratchPadPlugin = new ScratchPadPlugin();
// Schedule loading of the plugins after two seconds.
TaskEngine.getInstance().schedule(new TimerTask() {
public void run() {
final PluginManager pluginManager = PluginManager.getInstance();
SparkManager.getMainWindow().addMainWindowListener(
pluginManager);
pluginManager.initializePlugins();
// Subscriptions are always manual
Roster roster = SparkManager.getConnection().getRoster();
roster.setSubscriptionMode(Roster.SubscriptionMode.manual);
}
}, 2000);
// Check URI Mappings
SparkManager.getChatManager().handleURIMapping(Spark.ARGUMENTS);
}
/**
* Returns the status box for the User.
*
* @return the status box for the user.
*/
public StatusBar getStatusBar() {
return statusBox;
}
/**
* This is to handle agent to agent conversations.
*
* @param packet
* the smack packet to process.
*/
public void processPacket(final Packet packet) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
handleIncomingPacket(packet);
}
});
}
private void handleIncomingPacket(Packet packet) {
// We only handle message packets here.
if (packet instanceof Message) {
final Message message = (Message) packet;
boolean isGroupChat = message.getType() == Message.Type.groupchat;
// Check if Conference invite. If so, do not handle here.
if (message.getExtension("x", "jabber:x:conference") != null) {
return;
}
final String body = message.getBody();
boolean broadcast = message.getProperty("broadcast") != null;
if (Message.Type.normal == message.getType()) {
String from = message.getFrom();
from = from.substring(0, from.indexOf("@"));
String defaultSender=Default.getString("DEFAULT_MESSAGE_SENDER");
if (defaultSender.equalsIgnoreCase(from)) {
MessageBean ntb = new MessageBean();
String source = (String) message.getProperty("source");
String sourceId = (String) message.getProperty("sourceId");
String subject = message.getSubject();
String content = message.getBody();
String sendTime = (String) message.getProperty("sendTime");
String url = (String) message.getProperty("url");
ntb.setSource(source);
ntb.setSourceId(sourceId);
ntb.setSubject(subject);
ntb.setContent(content);
ntb.setIsread(MessageConstant.UNREAD);// 0代表未讀
ntb.setSendTime(sendTime);
ntb.setUrl(url);
HandleXML hand = new HandleXML();
ntb = SecritHelper.encode(ntb);
hand.addNewNode(ntb);
SparkToaster toaster = new SparkToaster();
toaster.showToaster(
"主题:" + message.getSubject() + "\n\n 消息来源:"
+ source + "\n\n\n 发送时间:" + sendTime, url);
}
}
// Handle offline message.
DelayInformation offlineInformation = (DelayInformation) message
.getExtension("x", "jabber:x:delay");
if (offlineInformation != null
&& (Message.Type.chat == message.getType() || Message.Type.normal == message
.getType())) {
handleOfflineMessage(message);
}
if (body == null || isGroupChat || broadcast
|| message.getType() == Message.Type.normal
|| message.getType() == Message.Type.headline
|| message.getType() == Message.Type.error) {
return;
}
// Create new chat room for Agent Invite.
final String from = packet.getFrom();
final String host = SparkManager.getSessionManager()
.getServerAddress();
// Don't allow workgroup notifications to come through here.
final String bareJID = StringUtils.parseBareAddress(from);
if (host.equalsIgnoreCase(from) || from == null) {
return;
}
ChatRoom room = null;
try {
room = SparkManager.getChatManager().getChatContainer()
.getChatRoom(bareJID);
} catch (ChatRoomNotFoundException e) {
// Ignore
}
// Check for non-existent rooms.
if (room == null) {
createOneToOneRoom(bareJID, message);
}
}
}
/**
* Creates a new room if necessary and inserts an offline message.
*
* @param message
* The Offline message.
*/
private void handleOfflineMessage(Message message) {
if (!ModelUtil.hasLength(message.getBody())
|| message.getFrom().contains("admin")) {
return;
}
String bareJID = StringUtils.parseBareAddress(message.getFrom());
ContactItem contact = contactList.getContactItemByJID(bareJID);
String nickname = StringUtils.parseName(bareJID);
if (contact != null) {
nickname = contact.getDisplayName();
}
// Create the room if it does not exist.
ChatRoom room = SparkManager.getChatManager().createChatRoom(bareJID,
nickname, nickname);
if (!SparkManager.getChatManager().getChatContainer().getChatFrame()
.isVisible()) {
SparkManager.getChatManager().getChatContainer().getChatFrame()
.setVisible(true);
}
// Insert offline message
room.getTranscriptWindow().insertMessage(nickname, message,
ChatManager.FROM_COLOR, Color.white);
room.addToTranscript(message, true);
// Send display and notified message back.
SparkManager.getMessageEventManager().sendDeliveredNotification(
message.getFrom(), message.getPacketID());
SparkManager.getMessageEventManager().sendDisplayedNotification(
message.getFrom(), message.getPacketID());
}
/**
* Creates a new room based on an anonymous user.
*
* @param bareJID
* the bareJID of the anonymous user.
* @param message
* the message from the anonymous user.
*/
private void createOneToOneRoom(String bareJID, Message message) {
ContactItem contact = contactList.getContactItemByJID(bareJID);
String nickname = StringUtils.parseName(bareJID);
if (contact != null) {
nickname = contact.getDisplayName();
} else {
// Attempt to load VCard from users who we are not subscribed to.
VCard vCard = SparkManager.getVCardManager().getVCard(bareJID);
if (vCard != null && vCard.getError() == null) {
String firstName = vCard.getFirstName();
String lastName = vCard.getLastName();
String userNickname = vCard.getNickName();
if (ModelUtil.hasLength(userNickname)) {
nickname = userNickname;
} else if (ModelUtil.hasLength(firstName)
&& ModelUtil.hasLength(lastName)) {
nickname = firstName + " " + lastName;
} else if (ModelUtil.hasLength(firstName)) {
nickname = firstName;
}
}
}
SparkManager.getChatManager().createChatRoom(bareJID, nickname,
nickname);
try {
insertMessage(bareJID, message);
} catch (ChatRoomNotFoundException e) {
Log.error("Could not find chat room.", e);
}
}
private void insertMessage(final String bareJID, final Message message)
throws ChatRoomNotFoundException {
ChatRoom chatRoom = SparkManager.getChatManager().getChatContainer()
.getChatRoom(bareJID);
chatRoom.insertMessage(message);
int chatLength = chatRoom.getTranscriptWindow().getDocument()
.getLength();
chatRoom.getTranscriptWindow().setCaretPosition(chatLength);
chatRoom.getChatInputEditor().requestFocusInWindow();
}
/**
* Returns the Workspace TabbedPane. If you wish to add your component,
* simply use addTab( name, icon, component ) call.
*
* @return the workspace JideTabbedPane
*/
public SparkTabbedPane getWorkspacePane() {
return workspacePane;
}
/**
* Returns the <code>ContactList</code> associated with this workspace.
*
* @return the ContactList associated with this workspace.
*/
public ContactList getContactList() {
return contactList;
}
public void changeCardLayout(String layout) {
cardLayout.show(cardPanel, layout);
}
public JPanel getCardPanel() {
return cardPanel;
}
/**
* Returns the <code>CommandPanel</code> of this Workspace.
*
* @return the CommandPanel.
*/
public CommandPanel getCommandPanel() {
return statusBox.getCommandPanel();
}
public ChatTranscriptPlugin getTranscriptPlugin() {
return transcriptPlugin;
}
/**
*
* description: 获取工具栏面板
*
* @author e40
* @project_name Lyim
* @class_name Workspace.java
* @version v1.0
* @createTime 2011-6-1 下午05:24:06 CommandPanel
* @return
*/
public CommandPanel getToolPanel() {
return toolPanel;
}
}
效果图如下:
可以集成门户,邮件系统等(部分中文未使用国际化,方便阅读)