/*
* PluginManager.java
* Copyright 2011 Connor Petty <cpmeister@users.sourceforge.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Created on Nov 5, 2011, 2:55:43 PM
*/
package pcgen.pluginmgr;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import pcgen.base.lang.UnreachableError;
import pcgen.system.PCGenSettings;
import pcgen.util.Logging;
/**
*
* @author Connor Petty <cpmeister@users.sourceforge.net>
*/
public final class PluginManager implements pcgen.system.PluginLoader
{
private static PluginManager instance;
private final Map<InteractivePlugin, Boolean> pluginMap;
private final List<PluginInfo> infoList;
private final MessageHandlerManager msgHandlerMgr;
private PluginManager()
{
pluginMap = new TreeMap<>(PLUGIN_PRIORITY_SORTER);
infoList = new ArrayList<>();
msgHandlerMgr = new MessageHandlerManager();
}
public synchronized static PluginManager getInstance()
{
if (instance == null)
{
instance = new PluginManager();
}
return instance;
}
/**
* A Comparator to sort interactive plugins by their priority.
*/
public static final Comparator<InteractivePlugin> PLUGIN_PRIORITY_SORTER = new Comparator<InteractivePlugin>()
{
@Override
public int compare(InteractivePlugin arg0, InteractivePlugin arg1)
{
return Integer.valueOf(arg0.getPriority()).compareTo(
arg1.getPriority());
}
};
public List<PluginInfo> getPluginInfoList()
{
return new ArrayList<>(infoList);
}
public void startAllPlugins()
{
PCGenMessageHandler dispatcher = msgHandlerMgr.getPostbox();
for(InteractivePlugin plugin : pluginMap.keySet())
{
if(pluginMap.get(plugin))
{
plugin.start(dispatcher);
msgHandlerMgr.addMember(plugin);
}
}
}
private String getLogName(Class<?> clazz, InteractivePlugin pl)
{
String logName = null;
try
{
Field f = clazz.getField("LOG_NAME");
logName = (String) f.get(pl);
}
catch (SecurityException e)
{
throw new UnreachableError("Access to Class " + clazz
+ " should not be prohibited", e);
}
catch (IllegalAccessException e)
{
throw new UnreachableError("Access to Method LOG_NAME in Class "
+ clazz + " should not be prohibited", e);
}
catch (NoSuchFieldException e)
{
Logging.errorPrint(clazz.getName()
+ " does not have LOG_NAME defined, "
+ "Plugin class implemented improperly");
}
catch (IllegalArgumentException e)
{
Logging.errorPrint(clazz.getName()
+ " does not have LOG_NAME defined to "
+ "take a Plugin as the argument, "
+ "Plugin class implemented improperly");
}
return logName;
}
@Override
public void loadPlugin(Class<?> clazz) throws Exception
{
InteractivePlugin pl = (InteractivePlugin) clazz.newInstance();
String logName = getLogName(clazz, pl);
String plName = pl.getPluginName();
boolean load = PCGenSettings.GMGEN_OPTIONS_CONTEXT.getBoolean(logName + ".Load", true);
if ((logName == null) || (plName == null))
{
Logging.log(Logging.WARNING, "Plugin " + clazz.getCanonicalName() + " needs"
+ " 'name' property.");
}
else
{
infoList.add(new PluginInfo(logName, plName));
pluginMap.put(pl, load);
}
}
@Override
public Class<?>[] getPluginClasses()
{
return new Class[]
{
InteractivePlugin.class
};
}
/**
* Add a new handler to the list of message handlers for
* GMGen and PCGen messages.
* @param handler The handler to be added.
*/
public void addMember(PCGenMessageHandler handler)
{
msgHandlerMgr.addMember(handler);
}
/**
* @return the postbox used to distribute messages.
*/
public PCGenMessageHandler getPostbox()
{
return msgHandlerMgr.getPostbox();
}
public static final class PluginInfo
{
public final String logName;
public final String pluginName;
private PluginInfo(String logName, String pluginName)
{
this.logName = logName;
this.pluginName = pluginName;
}
}
}