/** * $RCSfile: ,v $ * $Revision: $ * $Date: $ * * Copyright (C) 2004-2011 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.sparkimpl.plugin.phone; import org.jivesoftware.phone.client.BasePhoneEventListener; import org.jivesoftware.phone.client.HangUpEvent; import org.jivesoftware.phone.client.OnPhoneEvent; import org.jivesoftware.phone.client.PhoneActionException; import org.jivesoftware.phone.client.PhoneClient; import org.jivesoftware.phone.client.RingEvent; import org.jivesoftware.phone.client.action.PhoneActionIQProvider; import org.jivesoftware.phone.client.event.PhoneEventPacketExtensionProvider; import org.jivesoftware.resource.Res; import org.jivesoftware.resource.SparkRes; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.packet.Presence; import org.jivesoftware.smack.provider.ProviderManager; import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.spark.SparkManager; import org.jivesoftware.spark.phone.PhoneManager; import org.jivesoftware.spark.plugin.ContextMenuListener; import org.jivesoftware.spark.plugin.Plugin; import org.jivesoftware.spark.ui.ChatRoom; import org.jivesoftware.spark.ui.ChatRoomButton; import org.jivesoftware.spark.ui.ChatRoomListenerAdapter; import org.jivesoftware.spark.ui.ContactItem; import org.jivesoftware.spark.ui.ContactList; import org.jivesoftware.spark.ui.rooms.ChatRoomImpl; import org.jivesoftware.spark.util.ModelUtil; import org.jivesoftware.spark.util.ResourceUtils; import org.jivesoftware.spark.util.SwingTimerTask; import org.jivesoftware.spark.util.SwingWorker; import org.jivesoftware.spark.util.TaskEngine; import org.jivesoftware.spark.util.log.Log; import org.jivesoftware.sparkimpl.plugin.alerts.SparkToaster; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.util.TimerTask; public class PhonePlugin implements Plugin { public static PhoneClient phoneClient; private DialPanel dialPanel; // private Alert incomingDialog; private JFrame dialDialog; private Presence offPhonePresence; public void initialize() { ProviderManager.getInstance().addExtensionProvider("phone-event", "http://jivesoftware.com/xmlns/phone", new PhoneEventPacketExtensionProvider()); ProviderManager.getInstance().addIQProvider("phone-action", "http://jivesoftware.com/xmlns/phone", new PhoneActionIQProvider()); final XMPPConnection con = SparkManager.getConnection(); SwingWorker worker = new SwingWorker() { public Object construct() { try { phoneClient = new PhoneClient(con); // Add BaseListener phoneClient.addEventListener(new PhoneListener()); } catch (Exception e) { // Ignore because the user does not have support. //Log.debug(e); } return phoneClient; } public void finished() { if (phoneClient != null) { setupPhoneSystem(); } } }; worker.start(); } private void setupPhoneSystem() { // Add Dial Menu final JMenu viewMenu = SparkManager.getMainWindow().getMenuByName(Res.getString("menuitem.actions")); JMenuItem dialNumberMenu = new JMenuItem(SparkRes.getImageIcon(SparkRes.ON_PHONE_IMAGE)); ResourceUtils.resButton(dialNumberMenu, Res.getString("button.dial.number")); // Add Listener dialNumberMenu.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { dialPanel = new DialPanel(); dialPanel.getDialButton().addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String number = dialPanel.getNumberToDial(); if (ModelUtil.hasLength(number)) { dialPanel.setText(Res.getString("message.calling", number)); dialPanel.changeToRinging(); callExtension(number); } } }); dialDialog = PhoneDialog.invoke(dialPanel, Res.getString("title.dial.phone"), Res.getString("message.number.to.call"), null); dialPanel.getDialField().requestFocusInWindow(); dialPanel.getDialField().addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent e) { if (e.getKeyChar() == KeyEvent.VK_ENTER) { try { String number = dialPanel.getNumberToDial(); if (ModelUtil.hasLength(number)) { dialPanel.setText(Res.getString("message.calling", number)); dialPanel.changeToRinging(); callExtension(number); } e.consume(); } catch (Exception ex) { Log.error(ex); } } } }); } }); viewMenu.add(dialNumberMenu); // Add ChatRoomListener to call users based on JID SparkManager.getChatManager().addChatRoomListener(new ChatRoomListenerAdapter() { public void chatRoomOpened(final ChatRoom room) { if (room instanceof ChatRoomImpl) { final ChatRoomButton callButton = new ChatRoomButton("", SparkRes.getImageIcon(SparkRes.TELEPHONE_24x24)); callButton.setToolTipText(Res.getString("tooltip.place.a.call")); final ChatRoomImpl chatRoom = (ChatRoomImpl)room; boolean phoneEnabled = false; try { phoneEnabled = phoneClient.isPhoneEnabled(StringUtils.parseBareAddress(chatRoom.getParticipantJID())); } catch (Exception e) { Log.error(e); } if (phoneEnabled) { room.addChatRoomButton(callButton); callButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { callJID(chatRoom.getParticipantJID()); } }); } } } }); ContactList contactList = SparkManager.getWorkspace().getContactList(); contactList.addContextMenuListener(new ContextMenuListener() { public void poppingUp(Object object, final JPopupMenu popup) { if (object instanceof ContactItem) { final ContactItem item = (ContactItem)object; boolean phoneEnabled = false; try { phoneEnabled = phoneClient.isPhoneEnabled(item.getJID()); } catch (Exception e) { Log.error("There was an error retrieving phone information.", e); } if (phoneEnabled) { Action callAction = new AbstractAction() { private static final long serialVersionUID = 7221741748743018431L; public void actionPerformed(ActionEvent e) { callJID(item.getJID()); } }; callAction.putValue(Action.NAME, "Call"); callAction.putValue(Action.SMALL_ICON, SparkRes.getImageIcon(SparkRes.ON_PHONE_IMAGE)); popup.add(callAction); } } } public void poppingDown(JPopupMenu popup) { } public boolean handleDefaultAction(MouseEvent e) { return false; } }); } private class PhoneListener extends BasePhoneEventListener { public void handleOnPhone(OnPhoneEvent event) { if (dialDialog != null) { dialDialog.setVisible(false); } // Set offline presence if necessary. if (offPhonePresence == null) { offPhonePresence = SparkManager.getWorkspace().getStatusBar().getPresence(); // Send on phone presence Presence onPhonePresence = new Presence(Presence.Type.available, "On Phone", -1, Presence.Mode.away); SparkManager.getSessionManager().changePresence(onPhonePresence); } } public void handleHangUp(HangUpEvent event) { if (dialDialog != null) { dialDialog.setVisible(false); } if (offPhonePresence != null) { // Set user to previous presence state when all phone calls are hung up. SparkManager.getSessionManager().changePresence(offPhonePresence); offPhonePresence = null; } else { // If no previous state available, set status to Available Presence availablePresence = new Presence(Presence.Type.available, "Available", 1, Presence.Mode.available); SparkManager.getSessionManager().changePresence(availablePresence); offPhonePresence = null; } } public void handleRing(final RingEvent event) { final TimerTask task = new SwingTimerTask() { public void doRun() { String callerID = event.getCallerID(); if (ModelUtil.hasLength(callerID)) { String number = PhoneManager.getNumbersFromPhone(callerID); if (PhoneManager.getInstance().containsCurrentCall(number)) { return; } } displayRingUI(event); } }; TaskEngine.getInstance().schedule(task, 1000); } } private void displayRingUI(RingEvent event) { IncomingCall incomingCall = new IncomingCall(); boolean idExists = false; if (ModelUtil.hasLength(event.getCallerIDName())) { incomingCall.setCallerName(event.getCallerIDName()); idExists = true; } if (ModelUtil.hasLength(event.getCallerID())) { incomingCall.setCallerNumber(event.getCallerID()); idExists = true; } if (!idExists) { incomingCall.setCallerName(Res.getString("message.no.caller.id")); } SparkToaster toasterManager = new SparkToaster(); toasterManager.setTitle("Incoming Phone Call"); toasterManager.setDisplayTime(5000); toasterManager.showToaster(SparkRes.getImageIcon(SparkRes.ON_PHONE_IMAGE)); toasterManager.setComponent(incomingCall); } public void callExtension(final String number) { final Runnable caller = new Runnable() { public void run() { try { phoneClient.dialByExtension(number); } catch (PhoneActionException e) { Log.error(e); } } }; TaskEngine.getInstance().submit(caller); } public void callJID(final String jid) { final Runnable caller = new Runnable() { public void run() { try { phoneClient.dialByJID(jid); } catch (PhoneActionException e) { Log.error(e); } } }; TaskEngine.getInstance().submit(caller); } public static PhoneClient getPhoneClient() { return phoneClient; } public void shutdown() { } public boolean canShutDown() { return true; } public void uninstall() { // Do nothing. } }