// **********************************************************************
//
// Copyright (c) 2003-2010 ZeroC, Inc. All rights reserved.
//
// This copy of Ice is licensed to you under the terms described in the
// ICE_LICENSE file included in this distribution.
//
// **********************************************************************
package Ice;
public final class PluginManagerI implements PluginManager
{
private static String _kindOfObject = "plugin";
public synchronized void
initializePlugins()
{
if(_initialized)
{
InitializationException ex = new InitializationException();
ex.reason = "plug-ins already initialized";
throw ex;
}
//
// Invoke initialize() on the plug-ins, in the order they were loaded.
//
java.util.List<Plugin> initializedPlugins = new java.util.ArrayList<Plugin>();
try
{
for(Plugin p : _initOrder)
{
p.initialize();
initializedPlugins.add(p);
}
}
catch(RuntimeException ex)
{
//
// Destroy the plug-ins that have been successfully initialized, in the
// reverse order.
//
java.util.ListIterator<Plugin> i = initializedPlugins.listIterator(initializedPlugins.size());
while(i.hasPrevious())
{
Plugin p = i.previous();
try
{
p.destroy();
}
catch(RuntimeException e)
{
// Ignore.
}
}
throw ex;
}
_initialized = true;
}
public synchronized String[]
getPlugins()
{
java.util.ArrayList<String> names = new java.util.ArrayList<String>();
for(java.util.Map.Entry<String, Plugin> p : _plugins.entrySet())
{
names.add(p.getKey());
}
return names.toArray(new String[0]);
}
public synchronized Plugin
getPlugin(String name)
{
if(_communicator == null)
{
throw new CommunicatorDestroyedException();
}
Plugin p = _plugins.get(name);
if(p != null)
{
return p;
}
NotRegisteredException ex = new NotRegisteredException();
ex.id = name;
ex.kindOfObject = _kindOfObject;
throw ex;
}
public synchronized void
addPlugin(String name, Plugin plugin)
{
if(_communicator == null)
{
throw new CommunicatorDestroyedException();
}
if(_plugins.containsKey(name))
{
AlreadyRegisteredException ex = new AlreadyRegisteredException();
ex.id = name;
ex.kindOfObject = _kindOfObject;
throw ex;
}
_plugins.put(name, plugin);
}
public synchronized void
destroy()
{
if(_communicator != null)
{
if(_initialized)
{
for(java.util.Map.Entry<String, Plugin> p : _plugins.entrySet())
{
try
{
p.getValue().destroy();
}
catch(RuntimeException ex)
{
Ice.Util.getProcessLogger().warning("unexpected exception raised by plug-in `" + p.getKey() +
"' destruction:\n" + ex.toString());
}
}
}
_communicator = null;
}
}
public
PluginManagerI(Communicator communicator)
{
_communicator = communicator;
_initialized = false;
}
public void
loadPlugins(StringSeqHolder cmdArgs)
{
assert(_communicator != null);
//
// Load and initialize the plug-ins defined in the property set
// with the prefix "Ice.Plugin.". These properties should
// have the following format:
//
// Ice.Plugin.name[.<language>]=entry_point [args]
//
// If the Ice.PluginLoadOrder property is defined, load the
// specified plug-ins in the specified order, then load any
// remaining plug-ins.
//
final String prefix = "Ice.Plugin.";
Properties properties = _communicator.getProperties();
java.util.Map<String, String> plugins = properties.getPropertiesForPrefix(prefix);
final String[] loadOrder = properties.getPropertyAsList("Ice.PluginLoadOrder");
for(String name : loadOrder)
{
if(_plugins.containsKey(name))
{
PluginInitializationException ex = new PluginInitializationException();
ex.reason = "plug-in `" + name + "' already loaded";
throw ex;
}
String key = "Ice.Plugin." + name + ".java";
boolean hasKey = plugins.containsKey(key);
if(hasKey)
{
plugins.remove("Ice.Plugin." + name);
}
else
{
key = "Ice.Plugin." + name;
hasKey = plugins.containsKey(key);
}
if(hasKey)
{
final String value = plugins.get(key);
loadPlugin(name, value, cmdArgs);
plugins.remove(key);
}
else
{
PluginInitializationException ex = new PluginInitializationException();
ex.reason = "plug-in `" + name + "' not defined";
throw ex;
}
}
//
// Load any remaining plug-ins that weren't specified in PluginLoadOrder.
//
while(!plugins.isEmpty())
{
java.util.Iterator<java.util.Map.Entry<String, String> > p = plugins.entrySet().iterator();
java.util.Map.Entry<String, String> entry = p.next();
String name = entry.getKey().substring(prefix.length());
int dotPos = name.lastIndexOf('.');
if(dotPos != -1)
{
String suffix = name.substring(dotPos + 1);
if(suffix.equals("cpp") || suffix.equals("clr"))
{
//
// Ignored
//
p.remove();
}
else if(suffix.equals("java"))
{
name = name.substring(0, dotPos);
loadPlugin(name, entry.getValue(), cmdArgs);
p.remove();
//
// Don't want to load this one if it's there!
//
plugins.remove("Ice.Plugin." + name);
}
else
{
//
// Name is just a regular name that happens to contain a dot
//
dotPos = -1;
}
}
if(dotPos == -1)
{
//
// Is there a .java entry?
//
String value = entry.getValue();
p.remove();
String javaValue = plugins.remove("Ice.Plugin." + name + ".java");
if(javaValue != null)
{
value = javaValue;
}
loadPlugin(name, value, cmdArgs);
}
}
}
private void
loadPlugin(String name, String pluginSpec, StringSeqHolder cmdArgs)
{
assert(_communicator != null);
//
// Separate the entry point from the arguments.
//
String className;
String[] args;
int pos = pluginSpec.indexOf(' ');
if(pos == -1)
{
pos = pluginSpec.indexOf('\t');
}
if(pos == -1)
{
pos = pluginSpec.indexOf('\n');
}
if(pos == -1)
{
className = pluginSpec;
args = new String[0];
}
else
{
className = pluginSpec.substring(0, pos);
args = pluginSpec.substring(pos).trim().split("[ \t\n]+", pos);
}
//
// Convert command-line options into properties. First we
// convert the options from the plug-in configuration, then
// we convert the options from the application command-line.
//
Properties properties = _communicator.getProperties();
args = properties.parseCommandLineOptions(name, args);
cmdArgs.value = properties.parseCommandLineOptions(name, cmdArgs.value);
//
// Instantiate the class.
//
PluginFactory pluginFactory = null;
try
{
Class<?> c = IceInternal.Util.getInstance(_communicator).findClass(className);
if(c == null)
{
PluginInitializationException e = new PluginInitializationException();
e.reason = "class " + className + " not found";
throw e;
}
java.lang.Object obj = c.newInstance();
try
{
pluginFactory = (PluginFactory)obj;
}
catch(ClassCastException ex)
{
PluginInitializationException e = new PluginInitializationException();
e.reason = "class " + className + " does not implement Ice.PluginFactory";
e.initCause(ex);
throw e;
}
}
catch(IllegalAccessException ex)
{
PluginInitializationException e = new PluginInitializationException();
e.reason = "unable to access default constructor in class " + className;
e.initCause(ex);
throw e;
}
catch(InstantiationException ex)
{
PluginInitializationException e = new PluginInitializationException();
e.reason = "unable to instantiate class " + className;
e.initCause(ex);
throw e;
}
//
// Invoke the factory.
//
Plugin plugin = null;
try
{
plugin = pluginFactory.create(_communicator, name, args);
}
catch(PluginInitializationException ex)
{
throw ex;
}
catch(Throwable ex)
{
PluginInitializationException e = new PluginInitializationException();
e.reason = "exception in factory " + className;
e.initCause(ex);
throw e;
}
if(plugin == null)
{
PluginInitializationException e = new PluginInitializationException();
e.reason = "failure in factory " + className;
throw e;
}
_plugins.put(name, plugin);
_initOrder.add(plugin);
}
private Communicator _communicator;
private java.util.Map<String, Plugin> _plugins = new java.util.HashMap<String, Plugin>();
private java.util.List<Plugin> _initOrder = new java.util.ArrayList<Plugin>();
private boolean _initialized;
}