Changeset 2779


Ignore:
Timestamp:
02/11/10 13:41:52 (11 years ago)
Author:
gkronber
Message:

Added a way to store information why a plugin is disabled in plugin descriptions as suggested by abeham after code review. #863.

Location:
trunk/sources/HeuristicLab.PluginInfrastructure
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.PluginInfrastructure/Advanced/InstallationManager.cs

    r2778 r2779  
    105105      StringBuilder builder = new StringBuilder();
    106106      builder.AppendLine("Problem report:");
    107       var missingFiles = from x in desc.Files
    108                          where !File.Exists(x.Name)
    109                          select x.Name;
    110       if (missingFiles.Count() > 0) {
    111         foreach (string fileName in from file in desc.Files select file.Name) {
    112           if (!File.Exists(fileName)) builder.Append("Missing file: ").AppendLine(fileName);
    113         }
    114         return builder.ToString();
    115       } else {
    116         // or any dependency is disabled
    117         var disabledDependencies = from x in desc.Dependencies
    118                                    where x.PluginState == PluginState.Disabled
    119                                    select x;
    120         if (disabledDependencies.Count() > 0) {
    121           foreach (var dependency in disabledDependencies) {
    122             builder.Append(dependency.Name).AppendLine(" is disabled.").AppendLine(DetermineProblem(dependency));
    123           }
    124           return builder.ToString();
    125         } else {
    126           // or any dependency is missing / not installed
    127           var declaredDependencies = GetDeclaredDependencies(desc);
    128           if (declaredDependencies.Count() != desc.Dependencies.Count()) {
    129             var missingDependencies = from x in declaredDependencies
    130                                       where !desc.Dependencies.Any(dep => dep.Name == x)
    131                                       select x;
    132             builder.AppendLine("Necessary dependencies are missing:");
    133             foreach (string missingDependency in missingDependencies) {
    134               builder.AppendLine(missingDependency);
    135             }
    136           } else {
    137             // or there was a problem loading the assemblies
    138             builder.AppendLine("There was a problem while loading assemblies: ");
    139             foreach (string assemblyLocation in desc.AssemblyLocations) {
    140               builder.AppendLine(assemblyLocation + ": " + AssemblyName.GetAssemblyName(assemblyLocation).FullName);
    141             }
    142             return builder.ToString();
    143           }
    144         }
    145       }
    146       return "There is an unknown problem with plugin: " + desc.Name;
     107      builder.AppendLine(desc.LoadingErrorInformation);
     108      return builder.ToString();
    147109    }
    148110
  • trunk/sources/HeuristicLab.PluginInfrastructure/Manager/PluginDescription.cs

    r2778 r2779  
    9797    }
    9898
     99    private string loadingErrorInformation;
     100    /// <summary>
     101    /// Gets the error message why this plugin has been disabled.
     102    /// </summary>
     103    internal string LoadingErrorInformation {
     104      get {
     105        return loadingErrorInformation;
     106      }
     107    }
    99108
    100109    private List<PluginFile> files = new List<PluginFile>();
     
    126135    }
    127136
    128    
     137
    129138    /// <summary>
    130139    /// Gets the locations (file names) of the assemblies that belong to this plugin.
     
    138147    }
    139148
    140     internal void Disable() {
     149    internal void Disable(string loadingErrorInformation) {
    141150      if (pluginState != PluginState.Undefined)
    142151        throw new InvalidOperationException("Can't disabled a plugin in state " + pluginState);
    143152      pluginState = PluginState.Disabled;
     153      this.loadingErrorInformation = loadingErrorInformation;
    144154    }
    145155
  • trunk/sources/HeuristicLab.PluginInfrastructure/Manager/PluginValidator.cs

    r2778 r2779  
    190190      foreach (var desc in pluginDescriptions.Where(x => x.PluginState != PluginState.Disabled)) {
    191191        try {
     192          var missingAssemblies = new List<string>();
    192193          foreach (var asmLocation in desc.AssemblyLocations) {
    193194            // the assembly must have been loaded in ReflectionOnlyDlls
    194195            // so we simply determine the name of the assembly and try to find it in the cache of loaded assemblies
    195196            var asmName = AssemblyName.GetAssemblyName(asmLocation);
    196 
    197197            if (!reflectionOnlyAssemblies.ContainsKey(asmName.FullName)) {
    198               desc.Disable();
    199               break; // as soon as one assembly is not available disable the plugin and check the next plugin description
     198              missingAssemblies.Add(asmName.FullName);
    200199            }
    201200          }
    202         }
    203         catch (BadImageFormatException) {
     201          if (missingAssemblies.Count > 0) {
     202            StringBuilder errorStrBuiler = new StringBuilder();
     203            errorStrBuiler.AppendLine("Missing assemblies:");
     204            foreach (string missingAsm in missingAssemblies) {
     205              errorStrBuiler.AppendLine(missingAsm);
     206            }
     207            desc.Disable(errorStrBuiler.ToString());
     208          }
     209        }
     210        catch (BadImageFormatException ex) {
    204211          // disable the plugin
    205           desc.Disable();
    206         }
    207         catch (FileNotFoundException) {
     212          desc.Disable("Problem while loading plugin assemblies:" + Environment.NewLine + "BadImageFormatException: " + ex.Message);
     213        }
     214        catch (FileNotFoundException ex) {
    208215          // disable the plugin
    209           desc.Disable();
    210         }
    211         catch (FileLoadException) {
     216          desc.Disable("Problem while loading plugin assemblies:" + Environment.NewLine + "FileNotFoundException: " + ex.Message);
     217        }
     218        catch (FileLoadException ex) {
    212219          // disable the plugin
    213           desc.Disable();
    214         }
    215         catch (ArgumentException) {
     220          desc.Disable("Problem while loading plugin assemblies:" + Environment.NewLine + "FileLoadException: " + ex.Message);
     221        }
     222        catch (ArgumentException ex) {
    216223          // disable the plugin
    217           desc.Disable();
    218         }
    219         catch (SecurityException) {
     224          desc.Disable("Problem while loading plugin assemblies:" + Environment.NewLine + "ArgumentException: " + ex.Message);
     225        }
     226        catch (SecurityException ex) {
    220227          // disable the plugin
    221           desc.Disable();
     228          desc.Disable("Problem while loading plugin assemblies:" + Environment.NewLine + "SecurityException: " + ex.Message);
    222229        }
    223230      }
     
    370377    private void BuildDependencyTree(IEnumerable<PluginDescription> pluginDescriptions) {
    371378      foreach (var desc in pluginDescriptions) {
     379        var missingDependencies = new List<PluginDependency>();
    372380        foreach (var dependency in pluginDependencies[desc]) {
    373381          var matchingDescriptions = from availablePlugin in pluginDescriptions
     
    378386            desc.AddDependency(matchingDescriptions.Single());
    379387          } else {
    380             // no plugin description that matches the dependency name is available => plugin is disabled
    381             desc.Disable(); break;
    382           }
     388            missingDependencies.Add(dependency);
     389          }
     390        }
     391        // no plugin description that matches the dependencies are available => plugin is disabled
     392        if (missingDependencies.Count > 0) {
     393          StringBuilder errorStrBuilder = new StringBuilder();
     394          errorStrBuilder.AppendLine("Missing dependencies:");
     395          foreach (var missingDep in missingDependencies) {
     396            errorStrBuilder.AppendLine(missingDep.Name + " " + missingDep.Version);
     397          }
     398          desc.Disable(errorStrBuilder.ToString());
    383399        }
    384400      }
     
    409425    private void CheckPluginDependencyCycles(IEnumerable<PluginDescription> pluginDescriptions) {
    410426      foreach (var plugin in pluginDescriptions) {
    411         // if the plugin is not disabled anyway check if there are cycles
     427        // if the plugin is not disabled check if there are cycles
    412428        if (plugin.PluginState != PluginState.Disabled && HasCycleInDependencies(plugin, plugin.Dependencies)) {
    413           plugin.Disable();
     429          plugin.Disable("Dependency graph has a cycle.");
    414430        }
    415431      }
     
    429445    private void CheckPluginDependencies(IEnumerable<PluginDescription> pluginDescriptions) {
    430446      foreach (PluginDescription pluginDescription in pluginDescriptions.Where(x => x.PluginState != PluginState.Disabled)) {
    431         if (IsAnyDependencyDisabled(pluginDescription)) {
    432           pluginDescription.Disable();
    433         }
    434       }
    435     }
    436 
    437 
    438     private bool IsAnyDependencyDisabled(PluginDescription descr) {
    439       if (descr.PluginState == PluginState.Disabled) return true;
     447        List<PluginDescription> disabledPlugins = new List<PluginDescription>();
     448        if (IsAnyDependencyDisabled(pluginDescription, disabledPlugins)) {
     449          StringBuilder errorStrBuilder = new StringBuilder();
     450          errorStrBuilder.AppendLine("Dependencies are disabled:");
     451          foreach (var disabledPlugin in disabledPlugins) {
     452            errorStrBuilder.AppendLine(disabledPlugin.Name + " " + disabledPlugin.Version);
     453          }
     454          pluginDescription.Disable(errorStrBuilder.ToString());
     455        }
     456      }
     457    }
     458
     459
     460    private bool IsAnyDependencyDisabled(PluginDescription descr, List<PluginDescription> disabledPlugins) {
     461      if (descr.PluginState == PluginState.Disabled) {
     462        disabledPlugins.Add(descr);
     463        return true;
     464      }
    440465      foreach (PluginDescription dependency in descr.Dependencies) {
    441         if (IsAnyDependencyDisabled(dependency)) return true;
    442       }
    443       return false;
     466        IsAnyDependencyDisabled(dependency, disabledPlugins);
     467      }
     468      return disabledPlugins.Count > 0;
    444469    }
    445470
     
    473498    private void CheckPluginFiles(IEnumerable<PluginDescription> pluginDescriptions) {
    474499      foreach (PluginDescription desc in pluginDescriptions) {
    475         if (!CheckPluginFiles(desc)) {
    476           desc.Disable();
    477         }
    478       }
    479     }
    480 
    481     private bool CheckPluginFiles(PluginDescription pluginDescription) {
     500        IEnumerable<string> missingFiles;
     501        if (ArePluginFilesMissing(desc, out missingFiles)) {
     502          StringBuilder errorStrBuilder = new StringBuilder();
     503          errorStrBuilder.AppendLine("Missing files:");
     504          foreach (string fileName in missingFiles) {
     505            errorStrBuilder.AppendLine(fileName);
     506          }
     507          desc.Disable(errorStrBuilder.ToString());
     508        }
     509      }
     510    }
     511
     512    private bool ArePluginFilesMissing(PluginDescription pluginDescription, out IEnumerable<string> missingFiles) {
     513      List<string> missing = new List<string>();
    482514      foreach (string filename in pluginDescription.Files.Select(x => x.Name)) {
    483515        if (!FileLiesInDirectory(PluginDir, filename) ||
    484516          !File.Exists(filename)) {
    485           return false;
    486         }
    487       }
    488       return true;
     517          missing.Add(filename);
     518        }
     519      }
     520      missingFiles = missing;
     521      return missing.Count > 0;
    489522    }
    490523
Note: See TracChangeset for help on using the changeset viewer.