/**
* $RCSfile: ,v $
* $Revision: $
* $Date: $
*
* Copyright (C) 2011 eZuce Inc. 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.util;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Arrays;
import org.jivesoftware.LoginDialog;
import org.jivesoftware.smackx.muc.MultiUserChat;
import org.jivesoftware.spark.ButtonFactory;
import org.jivesoftware.spark.component.tabbedPane.SparkTabbedPane;
import org.jivesoftware.spark.ui.ChatContainer;
import org.jivesoftware.spark.ui.ChatRoom;
import org.jivesoftware.spark.ui.CommandPanel;
import org.jivesoftware.spark.ui.ContactGroup;
import org.jivesoftware.spark.ui.ContactInfoWindow;
import org.jivesoftware.spark.ui.ContactItem;
import org.jivesoftware.spark.ui.ContactList;
import org.jivesoftware.spark.ui.TranscriptWindow;
import org.jivesoftware.spark.ui.conferences.ConferenceServices;
import org.jivesoftware.spark.ui.conferences.GroupChatParticipantList;
import org.jivesoftware.spark.ui.rooms.ChatRoomImpl;
import org.jivesoftware.spark.ui.rooms.GroupChatRoom;
import org.jivesoftware.spark.ui.status.StatusBar;
import org.jivesoftware.spark.ui.themes.ThemePanel;
import org.jivesoftware.spark.util.log.Log;
/**
* This is a registry for components that may be replaced by plugins. Also
* doubles as a factory to instantiate those components.
*
*/
public final class UIComponentRegistry {
// use Spark defaults, so without any plugins we still have Spark's
// functionality
private static Class<? extends ContactItem> contactItemClass = ContactItem.class;
private static Class<? extends ContactInfoWindow> contactInfoWindowClass = ContactInfoWindow.class;
private static Class<? extends ContactGroup> contactGroupClass = ContactGroup.class;
private static Class<? extends ContactList> contactListClass = ContactList.class;
private static Class<? extends StatusBar> statusBarClass = StatusBar.class;
private static Class<? extends CommandPanel> commandPanelClass = CommandPanel.class;
private static Class<? extends SparkTabbedPane> workspaceTabPaneClass = SparkTabbedPane.class;
private static Class<? extends LoginDialog> loginDialogClass = LoginDialog.class;
private static Class<? extends ThemePanel> themePanelClass = ThemePanel.class;
private static Class<? extends ConferenceServices> conferenceServicesClass = ConferenceServices.class;
private static Class<? extends TranscriptWindow> transcriptWindowClass = TranscriptWindow.class;
private static Class<? extends ChatRoom> chatRoomClass = ChatRoomImpl.class;
private static Class<? extends GroupChatRoom> groupChatRoomClass=GroupChatRoom.class;
private static Class<? extends GroupChatParticipantList> groupChatParticipantListClass=GroupChatParticipantList.class;
private static Class<? extends ChatContainer> chatContainerClass = ChatContainer.class;
private static Class<? extends ButtonFactory> buttonFactoryClass = ButtonFactory.class;
private UIComponentRegistry() {
// disable instantiation
}
/**
* Registers a new class implementing a contact item.
*
* @param clazz
*/
public static void registerLoginDialog(Class<? extends LoginDialog> clazz) {
if (loginDialogClass != clazz) {
Log.debug("Registering new contract item class: "
+ clazz.getName());
loginDialogClass = clazz;
} else {
Log.warning("Class " + clazz.getName() + " already registered.");
}
}
/**
* Registers a new class implementing a contact item.
*
* @param clazz
*/
public static void registerContactItem(Class<? extends ContactItem> clazz) {
if (contactItemClass != clazz) {
Log.debug("Registering new contract item class: "
+ clazz.getName());
contactItemClass = clazz;
} else {
Log.warning("Class " + clazz.getName() + " already registered.");
}
}
/**
* Registers a new class implementing a contact info window.
*
* @param clazz
*/
public static void registerContactInfoWindow(
Class<? extends ContactInfoWindow> clazz) {
if (contactInfoWindowClass != clazz) {
Log.debug("Registering new contact info window class: "
+ clazz.getName());
contactInfoWindowClass = clazz;
} else {
Log.warning("Class " + clazz.getName() + " already registered.");
}
}
/**
* Registers a new class implementing a contact group.
*
* @param clazz
*/
public static void registerContactGroup(Class<? extends ContactGroup> clazz) {
if (contactGroupClass != clazz) {
Log.debug("Registering new contact group class: "
+ clazz.getName());
contactGroupClass = clazz;
} else {
Log.warning("Class " + clazz.getName() + " already registered.");
}
}
/**
* Registers a new class implementing a contact group.
*
* @param clazz
*/
public static void registerStatusBar(Class<? extends StatusBar> clazz) {
if (statusBarClass != clazz) {
Log.debug("Registering new status bar class: " + clazz.getName());
statusBarClass = clazz;
} else {
Log.warning("Class " + clazz.getName() + " already registered.");
}
}
/**
* Registers a new class implementing a command panel.
*
* @param clazz
*/
public static void registerCommandPanel(Class<? extends CommandPanel> clazz) {
if (commandPanelClass != clazz) {
Log.debug("Registering new command panel class: "
+ clazz.getName());
commandPanelClass = clazz;
} else {
Log.warning("Class " + clazz.getName() + " already registered.");
}
}
/**
* Registers a new class implementing a tab panel, for use within the main
* application window.
*
* @param clazz
*/
public static void registerWorkspaceTabPanel(Class<? extends SparkTabbedPane> clazz) {
if (workspaceTabPaneClass != clazz) {
Log.debug("Registering new search panel class: " + clazz.getName());
workspaceTabPaneClass = clazz;
} else {
Log.warning("Class " + clazz.getName() + " already registered.");
}
}
/**
* Registers a new class implementing a contact group. Registers a new class
* implementing a contact list.
*
* @param clazz
*/
public static void registerContactList(Class<? extends ContactList> clazz) {
if (contactListClass != clazz) {
Log.debug("Registering new contact list class: " + clazz.getName());
contactListClass = clazz;
} else {
Log.warning("Class " + clazz.getName() + " already registered.");
}
}
/**
* Registers a new class implementing a theme panel.
*
* @param clazz
*/
public static void registerThemePanel(Class<? extends ThemePanel> clazz) {
if (themePanelClass != clazz) {
Log.debug("Registering new theme panel class: " + clazz.getName());
themePanelClass = clazz;
} else {
Log.warning("Class " + clazz.getName() + " already registered.");
}
}
/**
* Registers a new class implementing conference services.
*
* @param clazz
*/
public static void registerConferenceServices(Class<? extends ConferenceServices> clazz) {
if (conferenceServicesClass != clazz) {
Log.debug("Registering new conference services class: " + clazz.getName());
conferenceServicesClass = clazz;
} else {
Log.warning("Class " + clazz.getName() + " already registered.");
}
}
/**
* Registers a new class implementing transcript window.
*
* @param clazz
*/
public static void registerTranscriptWindow(Class<? extends TranscriptWindow> clazz) {
if (transcriptWindowClass != clazz) {
Log.debug("Registering new transcript window class: " + clazz.getName());
transcriptWindowClass = clazz;
} else {
Log.warning("Class " + clazz.getName() + " already registered.");
}
}
/**
* Registers a new class implementing a chat room.
*
* @param clazz
*/
public static void registerChatRoom(Class<? extends ChatRoom> clazz) {
if (chatRoomClass != clazz) {
Log.debug("Registering new chat room class: " + clazz.getName());
chatRoomClass = clazz;
} else {
Log.warning("Class " + clazz.getName() + " already registered.");
}
}
public static void registerGroupChatRoom(Class<? extends GroupChatRoom> clazz) {
if (groupChatRoomClass != clazz){
Log.debug("Registering new group chat room class: " + clazz.getName());
groupChatRoomClass = clazz;
} else {
Log.warning("Class " + clazz.getName() + " already registered.");
}
}
public static void registerGroupChatParticipantList(Class<? extends GroupChatParticipantList> clazz) {
if (groupChatParticipantListClass != clazz){
Log.debug("Registering new group chat participant list class: " + clazz.getName());
groupChatParticipantListClass = clazz;
} else {
Log.warning("Class " + clazz.getName() + " already registered.");
}
}
/**
* Registers a new class implementing a chat room.
*
* @param clazz
*/
public static void registerChatContainer(Class<? extends ChatContainer> clazz) {
if (chatContainerClass != clazz) {
Log.debug("Registering new chat room class: " + clazz.getName());
chatContainerClass = clazz;
} else {
Log.warning("Class " + clazz.getName() + " already registered.");
}
}
/**
* Registers a new class implementing a button factory.
*
* @param clazz
*/
public static void registerButtonFactory(Class<? extends ButtonFactory> clazz) {
if (buttonFactoryClass != clazz) {
Log.debug("Registering new button factory class: " + clazz.getName());
buttonFactoryClass = clazz;
} else {
Log.warning("Class " + clazz.getName() + " already registered.");
}
}
/**
* Creates a new contact item object.
*
* @param alias
* @param nickname
* @param fullyQualifiedJID
*
* @return A new instance of the class currently registered as contact item.
*/
public static ContactItem createContactItem(String alias, String nickname,
String fullyQualifiedJID) {
// null breaks instantiation by reflection
final String nick = nickname != null ? nickname : "";
final String jid = fullyQualifiedJID != null ? fullyQualifiedJID : "";
final String aliass = alias != null ? alias : "";
return instantiate(contactItemClass, aliass, nick, jid);
}
/**
* Retrieves the contact info window instance (this is implemented as a
* singleton).
*
* @return The instance of the class currently registered as contact info
* window.
*/
public static ContactInfoWindow getContactInfoWindow() {
ContactInfoWindow instance = null;
try {
final Method m = contactInfoWindowClass.getMethod("getInstance");
final Object o = m.invoke(contactInfoWindowClass);
instance = contactInfoWindowClass.cast(o);
} catch (final Exception e) {
// not pretty but we're catching 5 exceptions we can do little about
Log.error(
"Error calling getInstance for "
+ contactInfoWindowClass.getName(), e);
}
return instance;
}
/**
* Creates a new contact group object.
*
* @param name
*
* @return A new instance of the class currently registered as contact
* group.
*/
public static ContactGroup createContactGroup(String name) {
return instantiate(contactGroupClass, name);
}
/**
* Creates a new contact group object
*
* @param name
*
* @return A new instance of the class currently registered as status bar.
*/
public static StatusBar createStatusBar() {
return instantiate(statusBarClass);
}
/**
* Creates a new command panel object
*
* @param name
*
* @return A new instance of the class currently registered as status bar.
*/
public static CommandPanel createCommandPanel() {
return instantiate(commandPanelClass);
}
/**
* Creates a new workspace tab panel object
*
* @param name
*
* @return
*/
public static SparkTabbedPane createWorkspaceTabPanel(int tabPosition) {
return instantiate(workspaceTabPaneClass, new Integer(tabPosition));
}
/**
* Creates a new login dialog panel object
*
* @param name
*
* @return
*/
public static LoginDialog createLoginDialog() {
return instantiate(loginDialogClass);
}
/**
* Creates a new contact list object.
*
* @return A new instance of the class currently registered as contact list.
*/
public static ContactList createContactList() {
return instantiate(contactListClass);
}
/**
* Creates a new theme panel object.
*
* @return A new instance of the class currently registered as theme panel.
*/
public static ThemePanel createThemePanel() {
return instantiate(themePanelClass);
}
/**
* Creates a new conference services object.
*
* @return A new instance of the class currently registered as conference
* services.
*/
public static ConferenceServices createConferenceServices() {
return instantiate(conferenceServicesClass);
}
/**
* Creates a new transcript window object.
*
* @return A new instance of the class currently registered as transcript
* window.
*/
public static TranscriptWindow createTranscriptWindow() {
return instantiate(transcriptWindowClass);
}
/**
* Creates a new chat room object.
*
* @return A new instance of the class currently registered as chat room.
*/
public static ChatRoom createChatRoom(String participantJID, String participantNickname, String title) {
return instantiate(chatRoomClass, participantJID, participantNickname, title);
}
public static GroupChatRoom createGroupChatRoom(MultiUserChat muc) {
return instantiate(groupChatRoomClass, muc);
}
public static GroupChatParticipantList createGroupChatParticipantList(){
return instantiate(groupChatParticipantListClass);
}
/**
* Creates a new chat container object.
*
* @return A new instance of the class currently registered as chat
* container.
*/
public static ChatContainer createChatContainer() {
return instantiate(chatContainerClass);
}
/**
* Retrieves the button factory instance (this is implemented as a
* singleton).
*
* @return The instance of the class currently registered as button factory.
*/
public static ButtonFactory getButtonFactory() {
ButtonFactory instance = null;
try {
final Method m = buttonFactoryClass.getMethod("getInstance");
final Object o = m.invoke(buttonFactoryClass);
instance = buttonFactoryClass.cast(o);
} catch (final Exception e) {
// not pretty but we're catching 5 exceptions we can do little about
Log.error("Error calling getInstance for " + buttonFactoryClass.getName(), e);
}
return instance;
}
/**
* Instantiate a given class.
*
* @param currentClass
* Class to instantiate.
* @param args
* Arguments for the class constructor.
* @return New instance, what else?
*/
private static <T> T instantiate(Class<? extends T> currentClass, Object... args) {
T instance = null;
Log.debug("Args: " + Arrays.toString(args));
try {
if (args != null) {
Class<? extends Object>[] classes = new Class<?>[args.length];
for (int i = 0; i < args.length; i++) {
classes[i] = args[i].getClass();
}
final Constructor<? extends T> ctor = currentClass.getDeclaredConstructor(classes);
instance = ctor.newInstance(args);
} else {
final Constructor<? extends T> ctor = currentClass.getDeclaredConstructor();
instance = ctor.newInstance();
}
} catch (final Exception e) {
// not pretty but we're catching several exceptions we can do little
// about
Log.error("Error calling constructor for " + currentClass.getName(), e);
}
return instance;
}
}