Пример #1
0
        public 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.
            //
            ArrayList initializedPlugins = new ArrayList();

            try
            {
                foreach (PluginInfo p in _plugins)
                {
                    try
                    {
                        p.plugin.initialize();
                    }
                    catch (PluginInitializationException ex)
                    {
                        throw ex;
                    }
                    catch (System.Exception ex)
                    {
                        PluginInitializationException e = new PluginInitializationException(ex);
                        e.reason = "plugin `" + p.name + "' initialization failed";
                        throw e;
                    }
                    initializedPlugins.Add(p.plugin);
                }
            }
            catch (System.Exception)
            {
                //
                // Destroy the plug-ins that have been successfully initialized, in the
                // reverse order.
                //
                initializedPlugins.Reverse();
                foreach (Plugin p in initializedPlugins)
                {
                    try
                    {
                        p.destroy();
                    }
                    catch (System.Exception)
                    {
                        // Ignore.
                    }
                }
                throw;
            }

            _initialized = true;
        }
Пример #2
0
        public 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.
            //
            ArrayList initializedPlugins = new ArrayList();
            try
            {
                foreach(PluginInfo p in _plugins)
                {
                    try
                    {
                        p.plugin.initialize();
                    }
                    catch(PluginInitializationException ex)
                    {
                        throw ex;
                    }
                    catch(System.Exception ex)
                    {
                        PluginInitializationException e = new PluginInitializationException(ex);
                        e.reason = "plugin `" + p.name + "' initialization failed";
                        throw e;
                    }
                    initializedPlugins.Add(p.plugin);
                }
            }
            catch(System.Exception)
            {
                //
                // Destroy the plug-ins that have been successfully initialized, in the
                // reverse order.
                //
                initializedPlugins.Reverse();
                foreach(Plugin p in initializedPlugins)
                {
                    try
                    {
                        p.destroy();
                    }
                    catch(System.Exception)
                    {
                        // Ignore.
                    }
                }
                throw;
            }

            _initialized = true;
        }
Пример #3
0
 ThreadHookPlugin(Communicator communicator, System.Action threadStart, System.Action threadStop)
 {
     if (communicator == null)
     {
         PluginInitializationException ex = new PluginInitializationException();
         ex.reason = "Communicator cannot be null";
         throw ex;
     }
     communicator.setThreadHook(threadStart, threadStop);
 }
Пример #4
0
        ThreadHookPlugin(Communicator communicator, System.Action threadStart, System.Action threadStop)
        {
            if (communicator == null)
            {
                PluginInitializationException ex = new PluginInitializationException();
                ex.reason = "Communicator cannot be null";
                throw ex;
            }

            IceInternal.Instance instance = IceInternal.Util.getInstance(communicator);
            instance.setThreadHook(threadStart, threadStop);
        }
Пример #5
0
        private void loadPlugin(string name, string pluginSpec, ref string[] cmdArgs)
        {
            Debug.Assert(_communicator != null);

            string[] args       = null;
            string   entryPoint = null;

            if (pluginSpec.Length > 0)
            {
                //
                // Split the entire property value into arguments. An entry point containing spaces
                // must be enclosed in quotes.
                //
                try
                {
                    args = IceUtilInternal.Options.split(pluginSpec);
                }
                catch (IceUtilInternal.Options.BadQuote ex)
                {
                    PluginInitializationException e = new PluginInitializationException();
                    e.reason = "invalid arguments for plug-in `" + name + "':\n" + ex.Message;
                    throw e;
                }

                Debug.Assert(args.Length > 0);

                entryPoint = args[0];

                //
                // Shift the arguments.
                //
                string[] tmp = new string[args.Length - 1];
                Array.Copy(args, 1, tmp, 0, args.Length - 1);
                args = tmp;

                //
                // 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 = properties.parseCommandLineOptions(name, cmdArgs);
            }

            string err = "unable to load plug-in `" + entryPoint + "': ";
            //
            // Always check the static plugin factory table first, it takes
            // precedence over the the entryPoint specified in the plugin
            // property value.
            //
            PluginFactory pluginFactory = null;

            if (!_factories.TryGetValue(name, out pluginFactory))
            {
                //
                // Extract the assembly name and the class name.
                //
                int sepPos = entryPoint.IndexOf(':');
                if (sepPos != -1)
                {
                    const string driveLetters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
                    if (entryPoint.Length > 3 &&
                        sepPos == 1 &&
                        driveLetters.IndexOf(entryPoint[0]) != -1 &&
                        (entryPoint[2] == '\\' || entryPoint[2] == '/'))
                    {
                        sepPos = entryPoint.IndexOf(':', 3);
                    }
                }
                if (sepPos == -1)
                {
                    PluginInitializationException e = new PluginInitializationException();
                    e.reason = err + "invalid entry point format";
                    throw e;
                }

                System.Reflection.Assembly pluginAssembly = null;
                string assemblyName = entryPoint.Substring(0, sepPos);
                string className    = entryPoint.Substring(sepPos + 1);

                try
                {
                    //
                    // First try to load the assembly using Assembly.Load, which will succeed
                    // if a fully-qualified name is provided or if a partial name has been qualified
                    // in configuration. If that fails, try Assembly.LoadFrom(), which will succeed
                    // if a file name is configured or a partial name is configured and DEVPATH is used.
                    //
                    // We catch System.Exception as this can fail with System.ArgumentNullException
                    // or System.IO.IOException depending of the .NET framework and platform.
                    //
                    try
                    {
                        pluginAssembly = System.Reflection.Assembly.Load(assemblyName);
                    }
                    catch (System.Exception ex)
                    {
                        try
                        {
                            pluginAssembly = System.Reflection.Assembly.LoadFrom(assemblyName);
                        }
                        catch (System.IO.IOException)
                        {
#pragma warning disable CA2200 // Rethrow to preserve stack details
                            throw ex;
#pragma warning restore CA2200 // Rethrow to preserve stack details
                        }
                    }
                }
                catch (System.Exception ex)
                {
                    PluginInitializationException e = new PluginInitializationException();
                    e.reason = err + "unable to load assembly: `" + assemblyName + "': " + ex.ToString();
                    throw e;
                }

                //
                // Instantiate the class.
                //
                System.Type c = null;
                try
                {
                    c = pluginAssembly.GetType(className, true);
                }
                catch (System.Exception ex)
                {
                    PluginInitializationException e = new PluginInitializationException(ex);
                    e.reason = err + "GetType failed for `" + className + "'";
                    throw e;
                }

                try
                {
                    pluginFactory = (PluginFactory)IceInternal.AssemblyUtil.createInstance(c);
                    if (pluginFactory == null)
                    {
                        PluginInitializationException e = new PluginInitializationException();
                        e.reason = err + "can't find constructor for `" + className + "'";
                        throw e;
                    }
                }
                catch (InvalidCastException ex)
                {
                    PluginInitializationException e = new PluginInitializationException(ex);
                    e.reason = err + "InvalidCastException to Ice.PluginFactory";
                    throw e;
                }
                catch (UnauthorizedAccessException ex)
                {
                    PluginInitializationException e = new PluginInitializationException(ex);
                    e.reason = err + "UnauthorizedAccessException: " + ex.ToString();
                    throw e;
                }
                catch (System.Exception ex)
                {
                    PluginInitializationException e = new PluginInitializationException(ex);
                    e.reason = err + "System.Exception: " + ex.ToString();
                    throw e;
                }
            }

            Plugin plugin = null;
            try
            {
                plugin = pluginFactory.create(_communicator, name, args);
            }
            catch (PluginInitializationException ex)
            {
                ex.reason = err + ex.reason;
                throw;
            }
            catch (System.Exception ex)
            {
                PluginInitializationException e = new PluginInitializationException(ex);
                e.reason = err + "System.Exception in factory.create: " + ex.ToString();
                throw e;
            }

            if (plugin == null)
            {
                PluginInitializationException ex = new PluginInitializationException();
                ex.reason = err + "factory.create returned null plug-in";
                throw ex;
            }

            PluginInfo info = new PluginInfo();
            info.name   = name;
            info.plugin = plugin;
            _plugins.Add(info);
        }
Пример #6
0
        public void loadPlugins(ref string[] cmdArgs)
        {
            Debug.Assert(_communicator != null);
            string     prefix     = "Ice.Plugin.";
            Properties properties = _communicator.getProperties();
            Dictionary <string, string> plugins = properties.getPropertiesForPrefix(prefix);

            //
            // First, load static plugin factories which were setup to load on
            // communicator initialization. If a matching plugin property is
            // set, we load the plugin with the plugin specification. The
            // entryPoint will be ignored but the rest of the plugin
            // specification might be used.
            //
            foreach (var name in _loadOnInitialization)
            {
                string key = "Ice.Plugin." + name + ".clr";
                string r   = null;
                plugins.TryGetValue(key, out r);
                if (r != null)
                {
                    plugins.Remove("Ice.Plugin." + name);
                }
                else
                {
                    key = "Ice.Plugin." + name;
                    plugins.TryGetValue(key, out r);
                }

                if (r != null)
                {
                    loadPlugin(name, r, ref cmdArgs);
                    plugins.Remove(key);
                }
                else
                {
                    loadPlugin(name, "", ref cmdArgs);
                }
            }

            //
            // 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]
            //
            // The code below is different from the Java/C++ algorithm
            // because C# must support full assembly names such as:
            //
            // Ice.Plugin.Logger=logger, Version=0.0.0.0, Culture=neutral:LoginPluginFactory
            //
            // If the Ice.PluginLoadOrder property is defined, load the
            // specified plug-ins in the specified order, then load any
            // remaining plug-ins.
            //

            string[] loadOrder = properties.getPropertyAsList("Ice.PluginLoadOrder");
            for (int i = 0; i < loadOrder.Length; ++i)
            {
                if (loadOrder[i].Length == 0)
                {
                    continue;
                }

                if (findPlugin(loadOrder[i]) != null)
                {
                    PluginInitializationException e = new PluginInitializationException();
                    e.reason = "plug-in `" + loadOrder[i] + "' already loaded";
                    throw e;
                }

                string key   = "Ice.Plugin." + loadOrder[i] + ".clr";
                string value = null;
                plugins.TryGetValue(key, out value);
                if (value != null)
                {
                    plugins.Remove("Ice.Plugin." + loadOrder[i]);
                }
                else
                {
                    key = "Ice.Plugin." + loadOrder[i];
                    plugins.TryGetValue(key, out value);
                }

                if (value != null)
                {
                    loadPlugin(loadOrder[i], value, ref cmdArgs);
                    plugins.Remove(key);
                }
                else
                {
                    PluginInitializationException e = new PluginInitializationException();
                    e.reason = "plug-in `" + loadOrder[i] + "' not defined";
                    throw e;
                }
            }

            //
            // Load any remaining plug-ins that weren't specified in PluginLoadOrder.
            //
            while (plugins.Count > 0)
            {
                IEnumerator <KeyValuePair <string, string> > p = plugins.GetEnumerator();
                p.MoveNext();
                string key  = p.Current.Key;
                string val  = p.Current.Value;
                string name = key.Substring(prefix.Length);

                int dotPos = name.LastIndexOf('.');
                if (dotPos != -1)
                {
                    string suffix = name.Substring(dotPos + 1);
                    if (suffix.Equals("cpp") || suffix.Equals("java"))
                    {
                        //
                        // Ignored
                        //
                        plugins.Remove(key);
                    }
                    else if (suffix.Equals("clr"))
                    {
                        name = name.Substring(0, dotPos);
                        loadPlugin(name, val, ref cmdArgs);
                        plugins.Remove(key);
                        plugins.Remove("Ice.Plugin." + name);
                    }
                    else
                    {
                        //
                        // Name is just a regular name that happens to contain a dot
                        //
                        dotPos = -1;
                    }
                }

                if (dotPos == -1)
                {
                    plugins.Remove(key);

                    //
                    // Is there a .clr entry?
                    //
                    string clrKey = "Ice.Plugin." + name + ".clr";
                    if (plugins.ContainsKey(clrKey))
                    {
                        val = plugins[clrKey];
                        plugins.Remove(clrKey);
                    }
                    loadPlugin(name, val, ref cmdArgs);
                }
            }
        }
Пример #7
0
        private void loadPlugin(string name, string pluginSpec, ref string[] cmdArgs)
        {
            Debug.Assert(_communicator != null);

            //
            // Split the entire property value into arguments. An entry point containing spaces
            // must be enclosed in quotes.
            //
            string[] args = null;
            try
            {
                args = IceUtilInternal.Options.split(pluginSpec);
            }
            catch (IceUtilInternal.Options.BadQuote ex)
            {
                PluginInitializationException e = new PluginInitializationException();
                e.reason = "invalid arguments for plug-in `" + name + "':\n" + ex.Message;
                throw e;
            }

            Debug.Assert(args.Length > 0);

            string entryPoint = args[0];

            //
            // Shift the arguments.
            //
            string[] tmp = new string[args.Length - 1];
            Array.Copy(args, 1, tmp, 0, args.Length - 1);
            args = tmp;

            //
            // 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 = properties.parseCommandLineOptions(name, cmdArgs);

            //
            // Extract the assembly name and the class name.
            //
            string err    = "unable to load plug-in `" + entryPoint + "': ";
            int    sepPos = entryPoint.IndexOf(':');

            if (sepPos != -1 && IceInternal.AssemblyUtil.platform_ == IceInternal.AssemblyUtil.Platform.Windows)
            {
                const string driveLetters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
                if (entryPoint.Length > 3 &&
                    sepPos == 1 &&
                    driveLetters.IndexOf(entryPoint[0]) != -1 &&
                    (entryPoint[2] == '\\' || entryPoint[2] == '/'))
                {
                    sepPos = entryPoint.IndexOf(':', 3);
                }
            }
            if (sepPos == -1)
            {
                PluginInitializationException e = new PluginInitializationException();
                e.reason = err + "invalid entry point format";
                throw e;
            }

            System.Reflection.Assembly pluginAssembly = null;
            string assemblyName = entryPoint.Substring(0, sepPos);
            string className    = entryPoint.Substring(sepPos + 1);

            try
            {
                //
                // First try to load the assembly using Assembly.Load, which will succeed
                // if a fully-qualified name is provided or if a partial name has been qualified
                // in configuration. If that fails, try Assembly.LoadFrom(), which will succeed
                // if a file name is configured or a partial name is configured and DEVPATH is used.
                //
                try
                {
                    pluginAssembly = System.Reflection.Assembly.Load(assemblyName);
                }
                catch (System.IO.IOException ex)
                {
                    try
                    {
                        pluginAssembly = System.Reflection.Assembly.LoadFrom(assemblyName);
                    }
                    catch (System.IO.IOException)
                    {
                        throw ex;
                    }
                }
            }
            catch (System.Exception ex)
            {
#if COMPACT
                //
                // IceSSL is not supported with the Compact Framework.
                //
                if (name == "IceSSL")
                {
                    if (!_sslWarnOnce)
                    {
                        _communicator.getLogger().warning(
                            "IceSSL plug-in not loaded: IceSSL is not supported with the .NET Compact Framework");
                        _sslWarnOnce = true;
                    }
                    return;
                }
#else
                //
                // IceSSL is not yet supported with Mono. We avoid throwing an exception in that case,
                // so the same configuration can be used with Mono or Visual C#.
                //
                if (IceInternal.AssemblyUtil.runtime_ == IceInternal.AssemblyUtil.Runtime.Mono && name == "IceSSL")
                {
                    if (!_sslWarnOnce)
                    {
                        _communicator.getLogger().warning(
                            "IceSSL plug-in not loaded: IceSSL is not supported with Mono");
                        _sslWarnOnce = true;
                    }
                    return;
                }
#endif

                PluginInitializationException e = new PluginInitializationException();
                e.reason = err + "unable to load assembly: `" + assemblyName + "': " + ex.ToString();
                throw e;
            }

            //
            // Instantiate the class.
            //
            PluginFactory pluginFactory = null;
            System.Type   c             = null;
            try
            {
                c = pluginAssembly.GetType(className, true);
            }
            catch (System.Exception ex)
            {
                PluginInitializationException e = new PluginInitializationException(ex);
                e.reason = err + "GetType failed for `" + className + "'";
                throw e;
            }

            try
            {
                pluginFactory = (PluginFactory)IceInternal.AssemblyUtil.createInstance(c);
                if (pluginFactory == null)
                {
                    PluginInitializationException e = new PluginInitializationException();
                    e.reason = err + "can't find constructor for `" + className + "'";
                    throw e;
                }
            }
            catch (System.InvalidCastException ex)
            {
                PluginInitializationException e = new PluginInitializationException(ex);
                e.reason = err + "InvalidCastException to Ice.PluginFactory";
                throw e;
            }
            catch (System.UnauthorizedAccessException ex)
            {
                PluginInitializationException e = new PluginInitializationException(ex);
                e.reason = err + "UnauthorizedAccessException: " + ex.ToString();
                throw e;
            }
            catch (System.Exception ex)
            {
                PluginInitializationException e = new PluginInitializationException(ex);
                e.reason = err + "System.Exception: " + ex.ToString();
                throw e;
            }

            Plugin plugin = null;
            try
            {
                plugin = pluginFactory.create(_communicator, name, args);
            }
            catch (PluginInitializationException ex)
            {
                ex.reason = err + ex.reason;
                throw ex;
            }
            catch (System.Exception ex)
            {
                PluginInitializationException e = new PluginInitializationException(ex);
                e.reason = err + "System.Exception in factory.create: " + ex.ToString();
                throw e;
            }

            if (plugin == null)
            {
                PluginInitializationException ex = new PluginInitializationException();
                ex.reason = err + "factory.create returned null plug-in";
                throw ex;
            }

            PluginInfo info = new PluginInfo();
            info.name   = name;
            info.plugin = plugin;
            _plugins.Add(info);
        }
Пример #8
0
        private void loadPlugin(string name, string pluginSpec, ref string[] cmdArgs)
        {
            Debug.Assert(_communicator != null);

            //
            // Split the entire property value into arguments. An entry point containing spaces
            // must be enclosed in quotes.
            //
            string[] args = null;
            try
            {
                args = IceUtilInternal.Options.split(pluginSpec);
            }
            catch(IceUtilInternal.Options.BadQuote ex)
            {
                PluginInitializationException e = new PluginInitializationException();
                e.reason = "invalid arguments for plug-in `" + name + "':\n" + ex.Message;
                throw e;
            }

            Debug.Assert(args.Length > 0);

            string entryPoint = args[0];

            //
            // Shift the arguments.
            //
            string[] tmp = new string[args.Length - 1];
            Array.Copy(args, 1, tmp, 0, args.Length - 1);
            args = tmp;

            //
            // 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 = properties.parseCommandLineOptions(name, cmdArgs);

            //
            // Extract the assembly name and the class name.
            //
            string err = "unable to load plug-in `" + entryPoint + "': ";
            int sepPos = entryPoint.IndexOf(':');
            if(sepPos != -1 && IceInternal.AssemblyUtil.platform_ == IceInternal.AssemblyUtil.Platform.Windows)
            {
                const string driveLetters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
                if(entryPoint.Length > 3 &&
                   sepPos == 1 &&
                   driveLetters.IndexOf(entryPoint[0]) != -1 &&
                   (entryPoint[2] == '\\' || entryPoint[2] == '/'))
                {
                    sepPos = entryPoint.IndexOf(':', 3);
                }
            }
            if(sepPos == -1)
            {
                PluginInitializationException e = new PluginInitializationException();
                e.reason = err + "invalid entry point format";
                throw e;
            }

            System.Reflection.Assembly pluginAssembly = null;
            string assemblyName = entryPoint.Substring(0, sepPos);
            string className = entryPoint.Substring(sepPos + 1);

            try
            {
                //
                // First try to load the assembly using Assembly.Load, which will succeed
                // if a fully-qualified name is provided or if a partial name has been qualified
                // in configuration. If that fails, try Assembly.LoadFrom(), which will succeed
                // if a file name is configured or a partial name is configured and DEVPATH is used.
                //
                try
                {
                    pluginAssembly = System.Reflection.Assembly.Load(assemblyName);
                }
                catch(System.IO.IOException ex)
                {
                    try
                    {
                        pluginAssembly = System.Reflection.Assembly.LoadFrom(assemblyName);
                    }
                    catch(System.IO.IOException)
                    {
                         throw ex;
                    }
                }
            }
            catch(System.Exception ex)
            {
                PluginInitializationException e = new PluginInitializationException();
                e.reason = err + "unable to load assembly: `" + assemblyName + "': " + ex.ToString();
                throw e;
            }

            //
            // Instantiate the class.
            //
            PluginFactory pluginFactory = null;
            System.Type c = null;
            try
            {
                c = pluginAssembly.GetType(className, true);
            }
            catch(System.Exception ex)
            {
                PluginInitializationException e = new PluginInitializationException(ex);
                e.reason = err + "GetType failed for `" + className + "'";
                throw e;
            }

            try
            {
                pluginFactory = (PluginFactory)IceInternal.AssemblyUtil.createInstance(c);
                if(pluginFactory == null)
                {
                    PluginInitializationException e = new PluginInitializationException();
                    e.reason = err + "can't find constructor for `" + className + "'";
                    throw e;
                }
            }
            catch(System.InvalidCastException ex)
            {
                PluginInitializationException e = new PluginInitializationException(ex);
                e.reason = err + "InvalidCastException to Ice.PluginFactory";
                throw e;
            }
            catch(System.UnauthorizedAccessException ex)
            {
                PluginInitializationException e = new PluginInitializationException(ex);
                e.reason = err + "UnauthorizedAccessException: " + ex.ToString();
                throw e;
            }
            catch(System.Exception ex)
            {
                PluginInitializationException e = new PluginInitializationException(ex);
                e.reason = err + "System.Exception: " + ex.ToString();
                throw e;
            }

            Plugin plugin = null;
            try
            {
                plugin = pluginFactory.create(_communicator, name, args);
            }
            catch(PluginInitializationException ex)
            {
                ex.reason = err + ex.reason;
                throw;
            }
            catch(System.Exception ex)
            {
                PluginInitializationException e = new PluginInitializationException(ex);
                e.reason = err + "System.Exception in factory.create: " + ex.ToString();
                throw e;
            }

            if(plugin == null)
            {
                PluginInitializationException ex = new PluginInitializationException();
                ex.reason = err + "factory.create returned null plug-in";
                throw ex;
            }

            PluginInfo info = new PluginInfo();
            info.name = name;
            info.plugin = plugin;
            _plugins.Add(info);
        }
Пример #9
0
        public void loadPlugins(ref string[] cmdArgs)
        {
            Debug.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]
            //
            // The code below is different from the Java/C++ algorithm
            // because C# must support full assembly names such as:
            //
            // Ice.Plugin.Logger=logger, Version=0.0.0.0, Culture=neutral:LoginPluginFactory
            //
            // If the Ice.PluginLoadOrder property is defined, load the
            // specified plug-ins in the specified order, then load any
            // remaining plug-ins.
            //
            string prefix = "Ice.Plugin.";
            Properties properties = _communicator.getProperties();
            Dictionary<string, string> plugins = properties.getPropertiesForPrefix(prefix);

            string[] loadOrder = properties.getPropertyAsList("Ice.PluginLoadOrder");
            for(int i = 0; i < loadOrder.Length; ++i)
            {
                if(loadOrder[i].Length == 0)
                {
                    continue;
                }

                if(findPlugin(loadOrder[i]) != null)
                {
                    PluginInitializationException e = new PluginInitializationException();
                    e.reason = "plug-in `" + loadOrder[i] + "' already loaded";
                    throw e;
                }

                string key = "Ice.Plugin." + loadOrder[i] + ".clr";
                bool hasKey = plugins.ContainsKey(key);
                if(hasKey)
                {
                    plugins.Remove("Ice.Plugin." + loadOrder[i]);
                }
                else
                {
                    key = "Ice.Plugin." + loadOrder[i];
                    hasKey = plugins.ContainsKey(key);
                }

                if(hasKey)
                {
                    string value = plugins[key];
                    loadPlugin(loadOrder[i], value, ref cmdArgs);
                    plugins.Remove(key);
                }
                else
                {
                    PluginInitializationException e = new PluginInitializationException();
                    e.reason = "plug-in `" + loadOrder[i] + "' not defined";
                    throw e;
                }
            }

            //
            // Load any remaining plug-ins that weren't specified in PluginLoadOrder.
            //
            while(plugins.Count > 0)
            {
                IEnumerator<KeyValuePair<string, string>> p = plugins.GetEnumerator();
                p.MoveNext();
                string key = p.Current.Key;
                string val = p.Current.Value;
                string name = key.Substring(prefix.Length);

                int dotPos = name.LastIndexOf('.');
                if(dotPos != -1)
                {
                    string suffix = name.Substring(dotPos + 1);
                    if(suffix.Equals("cpp") || suffix.Equals("java"))
                    {
                        //
                        // Ignored
                        //
                        plugins.Remove(key);
                    }
                    else if(suffix.Equals("clr"))
                    {
                        name = name.Substring(0, dotPos);
                        loadPlugin(name, val, ref cmdArgs);
                        plugins.Remove(key);
                        plugins.Remove("Ice.Plugin." + name);

                    }
                    else
                    {
                        //
                        // Name is just a regular name that happens to contain a dot
                        //
                        dotPos = -1;
                    }
                }

                if(dotPos == -1)
                {
                    plugins.Remove(key);

                    //
                    // Is there a .clr entry?
                    //
                    string clrKey = "Ice.Plugin." + name + ".clr";
                    if(plugins.ContainsKey(clrKey))
                    {
                        val = plugins[clrKey];
                        plugins.Remove(clrKey);
                    }
                    loadPlugin(name, val, ref cmdArgs);
                }
            }
        }
Пример #10
0
        private void loadPlugin(string name, string pluginSpec, ref string[] cmdArgs)
        {
            Debug.Assert(_communicator != null);

            //
            // Separate the entry point from the arguments. First
            // look for the :, then for the next whitespace. This
            // represents the end of the entry point.
            //
            // The remainder of the configuration line represents
            // the arguments.
            //
            string entryPoint = pluginSpec;
            string[] args = new string[0];
            int start = pluginSpec.IndexOf(':');
            if(start != -1)
            {
                //
                // Skip drive letter, if any.
                //
                if(pluginSpec.Length > 3 &&
                   start == 1 &&
                   System.Char.IsLetter(pluginSpec[0]) &&
                   (pluginSpec[2] == '\\' || pluginSpec[2] == '/'))
                {
                    start = pluginSpec.IndexOf(':', 3);
                }

                //
                // Find the whitespace.
                //
                int pos = pluginSpec.IndexOf(' ', start);
                if(pos == -1)
                {
                    pos = pluginSpec.IndexOf('\t', start);
                }
                if(pos == -1)
                {
                    pos = pluginSpec.IndexOf('\n', start);
                }
                if(pos != -1)
                {
                    entryPoint = pluginSpec.Substring(0, pos);
                    char[] delims = { ' ', '\t', '\n' };
                    args = pluginSpec.Substring(pos).Trim().Split(delims);
                }
            }

            //
            // 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 = properties.parseCommandLineOptions(name, cmdArgs);

            //
            // Retrieve the assembly name and the type.
            //
            string err = "unable to load plug-in '" + entryPoint + "': ";
            int sepPos = entryPoint.IndexOf(':');
            if(sepPos != -1)
            {
                if(entryPoint.Length > 3 &&
                   sepPos == 1 &&
                   System.Char.IsLetter(entryPoint[0]) &&
                   (entryPoint[2] == '\\' || entryPoint[2] == '/'))
                {
                    sepPos = entryPoint.IndexOf(':', 3);
                }
            }
            if (sepPos == -1)
            {
                PluginInitializationException e = new PluginInitializationException();
                e.reason = err + "invalid entry point format";
                throw e;
            }

            System.Reflection.Assembly pluginAssembly = null;
            string assemblyName = entryPoint.Substring(0, sepPos);
            try
            {
                //
                // First try to load the assemby using Assembly.Load which will succeed
                // if full name is configured or partial name has been qualified in config.
                // If that fails, try Assembly.LoadFrom() which will succeed if a file name
                // is configured or partial name is configured and DEVPATH is used.
                //
                try
                {
                    pluginAssembly = System.Reflection.Assembly.Load(assemblyName);
                }
                catch(System.IO.IOException ex)
                {
                    try
                    {
                        pluginAssembly = System.Reflection.Assembly.LoadFrom(assemblyName);
                    }
                    catch(System.IO.IOException)
                    {
                         throw ex;
                    }
                }
            }
            catch(System.Exception ex)
            {
            #if COMPACT
                //
                // IceSSL is not supported with the Compact Framework.
                //
                if(name == "IceSSL")
                {
                    if(!_sslWarnOnce)
                    {
                        _communicator.getLogger().warning(
                            "IceSSL plug-in not loaded: IceSSL is not supported with the .NET Compact Framework");
                        _sslWarnOnce = true;
                    }
                    return;
                }
            #else
                //
                // IceSSL is not yet supported with Mono. We avoid throwing an exception in that case,
                // so the same configuration can be used with Mono or Visual C#.
                //
                if(IceInternal.AssemblyUtil.runtime_ == IceInternal.AssemblyUtil.Runtime.Mono && name == "IceSSL")
                {
                    if(!_sslWarnOnce)
                    {
                        _communicator.getLogger().warning(
                            "IceSSL plug-in not loaded: IceSSL is not supported with Mono");
                        _sslWarnOnce = true;
                    }
                    return;
                }
            #endif

                PluginInitializationException e = new PluginInitializationException();
                e.reason = err + "unable to load assembly: '" + assemblyName + "': " + ex.ToString();
                throw e;
            }

            //
            // Instantiate the class.
            //
            PluginFactory pluginFactory = null;
            string className = entryPoint.Substring(sepPos + 1);
            System.Type c = null;
            try
            {
                c = pluginAssembly.GetType(className, true);
            }
            catch(System.Exception ex)
            {
                PluginInitializationException e = new PluginInitializationException(ex);
                e.reason = err + "GetType failed for '" + className + "'";
                throw e;
            }

            try
            {
                pluginFactory = (PluginFactory)IceInternal.AssemblyUtil.createInstance(c);
                if(pluginFactory == null)
                {
                    PluginInitializationException e = new PluginInitializationException();
                    e.reason = err + "Can't find constructor for '" + className + "'";
                    throw e;
                }
            }
            catch(System.InvalidCastException ex)
            {
                PluginInitializationException e = new PluginInitializationException(ex);
                e.reason = err + "InvalidCastException to Ice.PluginFactory";
                throw e;
            }
            catch(System.UnauthorizedAccessException ex)
            {
                PluginInitializationException e = new PluginInitializationException(ex);
                e.reason = err + "UnauthorizedAccessException: " + ex.ToString();
                throw e;
            }
            catch(System.Exception ex)
            {
                PluginInitializationException e = new PluginInitializationException(ex);
                e.reason = err + "System.Exception: " + ex.ToString();
                throw e;
            }

            Plugin plugin = null;
            try
            {
                plugin = pluginFactory.create(_communicator, name, args);
            }
            catch(PluginInitializationException ex)
            {
                ex.reason = err + ex.reason;
                throw ex;
            }
            catch(System.Exception ex)
            {
                PluginInitializationException e = new PluginInitializationException(ex);
                e.reason = err + "System.Exception in factory.create: " + ex.ToString();
                throw e;
            }

            if(plugin == null)
            {
                PluginInitializationException ex = new PluginInitializationException();
                ex.reason = err + "factory.create returned null plug-in";
                throw ex;
            }

            _plugins[name] = plugin;
            _initOrder.Add(plugin);
        }