/**
* $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.spark.phone;
import org.jivesoftware.resource.Res;
import org.jivesoftware.resource.SparkRes;
import org.jivesoftware.spark.ChatManager;
import org.jivesoftware.spark.SparkManager;
import org.jivesoftware.spark.plugin.ContextMenuListener;
import org.jivesoftware.spark.ui.ChatRoom;
import org.jivesoftware.spark.ui.ChatRoomButton;
import org.jivesoftware.spark.ui.ChatRoomListener;
import org.jivesoftware.spark.ui.ContactItem;
import org.jivesoftware.spark.ui.ContactList;
import org.jivesoftware.spark.ui.rooms.ChatRoomImpl;
import org.jivesoftware.spark.util.SwingWorker;
import org.jivesoftware.sparkimpl.plugin.phone.JMFInit;
import org.jivesoftware.Spark;
import javax.swing.Action;
import javax.swing.JMenu;
import javax.swing.JPopupMenu;
import javax.media.MediaLocator;
import javax.media.protocol.DataSource;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* Handles general phone behavior in Spark. This allows for many different phone systems
* to plug into Spark in a more elegant way.
*/
public class PhoneManager implements ChatRoomListener, ContextMenuListener {
private static PhoneManager singleton;
private static final Object LOCK = new Object();
private List<Phone> phones = new CopyOnWriteArrayList<Phone>();
private List<String> currentCalls = new ArrayList<String>();
// Static Media Locator
static private MediaLocator mediaLocator = null;
// Static Media Locator Preference
static private boolean useStaticLocator = false;
// Static using MediaLocator
static private boolean usingMediaLocator = false;
// Static DataSource
static private DataSource ds;
/**
* Returns the singleton instance of <CODE>PhoneManager</CODE>,
* creating it if necessary.
* <p/>
*
* @return the singleton instance of <Code>PhoneManager</CODE>
*/
public static PhoneManager getInstance() {
// Synchronize on LOCK to ensure that we don't end up creating
// two singletons.
synchronized (LOCK) {
if (null == singleton) {
PhoneManager controller = new PhoneManager();
singleton = controller;
return controller;
}
}
return singleton;
}
private PhoneManager() {
JMFInit.start(false);
if (Spark.isVista() || Spark.isLinux()) {
setUseStaticLocator(true);
}
}
private void addListeners() {
// Handle ChatRooms.
final ChatManager chatManager = SparkManager.getChatManager();
chatManager.addChatRoomListener(this);
// Handle ContextMenus.
final ContactList contactList = SparkManager.getWorkspace().getContactList();
contactList.addContextMenuListener(this);
}
public void addPhone(Phone phone) {
if (phones.isEmpty()) {
addListeners();
}
phones.add(phone);
}
public void removePhone(Phone phone) {
phones.remove(phone);
}
public void chatRoomOpened(final ChatRoom room) {
if (!phones.isEmpty() && room instanceof ChatRoomImpl) {
final ChatRoomImpl chatRoomImpl = (ChatRoomImpl) room;
final ChatRoomButton dialButton = new ChatRoomButton(SparkRes.getImageIcon(SparkRes.DIAL_PHONE_IMAGE_24x24));
dialButton.setToolTipText(Res.getString("tooltip.place.voice.call"));
final List<Action> actions = new ArrayList<Action>();
SwingWorker actionWorker = new SwingWorker() {
public Object construct() {
for (Phone phone : phones) {
final Collection<Action> phoneActions = phone.getPhoneActions(chatRoomImpl.getParticipantJID());
if (phoneActions != null) {
for (Action action : phoneActions) {
actions.add(action);
}
}
}
return actions;
}
public void finished() {
if (!actions.isEmpty()) {
room.addChatRoomButton(dialButton, true);
}
}
};
actionWorker.start();
dialButton.addMouseListener(new MouseAdapter() {
public void mousePressed(final MouseEvent e) {
SwingWorker worker = new SwingWorker() {
public Object construct() {
try {
Thread.sleep(50);
}
catch (InterruptedException e1) {
e1.printStackTrace();
}
return true;
}
public void finished() {
// Handle actions.
if (actions.size() > 0) {
// Display PopupMenu
final JPopupMenu menu = new JPopupMenu();
for (Action action : actions) {
menu.add(action);
}
menu.show(dialButton, e.getX(), e.getY());
}
}
};
worker.start();
}
});
}
}
public void chatRoomLeft(ChatRoom room) {
}
public void chatRoomClosed(ChatRoom room) {
}
public void chatRoomActivated(ChatRoom room) {
}
public void userHasJoined(ChatRoom room, String userid) {
}
public void userHasLeft(ChatRoom room, String userid) {
}
public void poppingUp(Object object, final JPopupMenu popup) {
if (!phones.isEmpty()) {
if (object instanceof ContactItem) {
final ContactItem contactItem = (ContactItem) object;
final List<Action> actions = new ArrayList<Action>();
SwingWorker worker = new SwingWorker() {
public Object construct() {
for (Phone phone : phones) {
final Collection<Action> itemActions = phone.getPhoneActions(contactItem.getJID());
for (Action action : itemActions) {
actions.add(action);
}
}
return null;
}
public void finished() {
if (actions.size() > 0) {
final JMenu dialMenu = new JMenu(Res.getString("title.dial.phone"));
dialMenu.setIcon(SparkRes.getImageIcon(SparkRes.DIAL_PHONE_IMAGE_16x16));
for (Action action : actions) {
dialMenu.add(action);
}
int count = popup.getComponentCount();
if (count > 2) {
popup.insert(dialMenu, 2);
}
popup.invalidate();
popup.validate();
popup.repaint();
}
}
};
worker.start();
}
}
}
public void poppingDown(JPopupMenu popup) {
}
public boolean handleDefaultAction(MouseEvent e) {
return false;
}
public void addCurrentCall(String phoneNumber) {
currentCalls.add(phoneNumber);
}
public void removeCurrentCall(String phoneNumber) {
currentCalls.remove(phoneNumber);
}
public boolean containsCurrentCall(String phoneNumber) {
return currentCalls.contains(phoneNumber);
}
public static String getNumbersFromPhone(String number) {
if (number == null) {
return null;
}
number = number.replace("-", "");
number = number.replace("(", "");
number = number.replace(")", "");
number = number.replace(" ", "");
if (number.startsWith("1")) {
number = number.substring(1);
}
return number;
}
public static MediaLocator getMediaLocator(String locator) {
MediaLocator auxLocator;
if (useStaticLocator) {
if (mediaLocator == null) {
mediaLocator = new MediaLocator(locator);
}
auxLocator = mediaLocator;
//usingMediaLocator=true;
} else {
auxLocator = new MediaLocator(locator);
}
return auxLocator;
}
public static DataSource getDataSource(String locator) {
if (ds == null) {
try {
ds = javax.media.Manager.createDataSource(getMediaLocator(locator));
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
return ds;
}
public static DataSource getDataSource(MediaLocator locator) {
if (ds == null) {
try {
ds = javax.media.Manager.createDataSource(locator);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
return ds;
}
public static boolean isUsingMediaLocator() {
return usingMediaLocator;
}
public static void setUsingMediaLocator(boolean usingMediaLocator) {
PhoneManager.usingMediaLocator = usingMediaLocator;
}
public static boolean isUseStaticLocator() {
return useStaticLocator;
}
public static void setUseStaticLocator(boolean useStaticLocator) {
PhoneManager.useStaticLocator = useStaticLocator;
}
}