Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Persistence/3.3/Core/ConfigurationService.cs @ 1625

Last change on this file since 1625 was 1625, checked in by epitzer, 15 years ago

Added PersistenceException used consistently for all error conditions in the persistence framework (#548)

File size: 6.9 KB
Line 
1using System;
2using System.IO;
3using System.Collections.Generic;
4using System.Reflection;
5using System.Text;
6using HeuristicLab.Persistence.Default.Xml;
7using HeuristicLab.Persistence.Interfaces;
8using HeuristicLab.Tracing;
9using HeuristicLab.Persistence.Core.Tokens;
10
11namespace HeuristicLab.Persistence.Core {
12
13  public class ConfigurationService {
14
15    private static ConfigurationService instance;
16    private readonly Dictionary<IFormat, Configuration> customConfigurations;
17    public Dictionary<Type, List<IFormatter>> Formatters { get; private set; }
18    public List<IDecomposer> Decomposers { get; private set; }
19    public List<IFormat> Formats { get; private set; }
20
21    public static ConfigurationService Instance {
22      get {
23        if (instance == null)
24          instance = new ConfigurationService();
25        return instance;
26      }
27    }
28
29    private ConfigurationService() {
30      Formatters = new Dictionary<Type, List<IFormatter>>();
31      Decomposers = new List<IDecomposer>();
32      customConfigurations = new Dictionary<IFormat, Configuration>();
33      Formats = new List<IFormat>();
34      Reset();
35      LoadSettings();
36    }
37
38    protected void LoadSettings() {
39      try {
40        if (String.IsNullOrEmpty(Properties.Settings.Default.CustomConfigurations) ||
41          String.IsNullOrEmpty(Properties.Settings.Default.CustomConfigurationsTypeCache))
42          return;
43        Deserializer deSerializer = new Deserializer(
44          XmlParser.ParseTypeCache(
45          new StringReader(
46            Properties.Settings.Default.CustomConfigurationsTypeCache)));
47        XmlParser parser = new XmlParser(
48          new StringReader(
49            Properties.Settings.Default.CustomConfigurations));
50        var newCustomConfigurations = (Dictionary<IFormat, Configuration>)
51          deSerializer.Deserialize(parser);
52        foreach (var config in newCustomConfigurations) {
53          customConfigurations[config.Key] = config.Value;
54        }
55      } catch (Exception e) {
56        Logger.Warn("Could not load settings.", e);
57      }
58    }
59
60    protected void SaveSettings() {
61      Serializer serializer = new Serializer(
62        customConfigurations,
63        GetDefaultConfig(new XmlFormat()),
64        "CustomConfigurations");
65      XmlGenerator generator = new XmlGenerator();
66      StringBuilder configurationString = new StringBuilder();
67      foreach (ISerializationToken token in serializer) {
68        configurationString.Append(generator.Format(token));
69      }
70      StringBuilder configurationTypeCacheString = new StringBuilder();
71      foreach (string s in generator.Format(serializer.TypeCache))
72        configurationTypeCacheString.Append(s);
73      Properties.Settings.Default.CustomConfigurations =
74        configurationString.ToString();
75      Properties.Settings.Default.CustomConfigurationsTypeCache =
76        configurationTypeCacheString.ToString();
77      Properties.Settings.Default.Save();
78    }
79
80    public void Reset() {
81      customConfigurations.Clear();
82      Formatters.Clear();
83      Decomposers.Clear();
84      Assembly defaultAssembly = Assembly.GetExecutingAssembly();
85      DiscoverFrom(defaultAssembly);
86      foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies())
87        if (a != defaultAssembly)
88          DiscoverFrom(a);
89      SortDecomposers();
90    }
91
92    class PriortiySorter : IComparer<IDecomposer> {
93      public int Compare(IDecomposer x, IDecomposer y) {
94        return y.Priority - x.Priority;
95      }
96    }
97
98    protected void SortDecomposers() {
99      Decomposers.Sort(new PriortiySorter());
100    }
101
102    protected void DiscoverFrom(Assembly a) {
103      foreach (Type t in a.GetTypes()) {
104        if (t.GetInterface(typeof(IFormatter).FullName) != null) {
105          try {
106            IFormatter formatter = (IFormatter)Activator.CreateInstance(t, true);
107            if (!Formatters.ContainsKey(formatter.SerialDataType)) {
108              Formatters.Add(formatter.SerialDataType, new List<IFormatter>());
109            }
110            Formatters[formatter.SerialDataType].Add(formatter);
111            Logger.Debug(String.Format("discovered formatter {0} ({1} -> {2})",
112              t.VersionInvariantName(),
113              formatter.SourceType.VersionInvariantName(),
114              formatter.SerialDataType.VersionInvariantName()));
115          } catch (MissingMethodException e) {
116            Logger.Warn("Could not instantiate " + t.VersionInvariantName(), e);
117          } catch (ArgumentException e) {
118            Logger.Warn("Could not instantiate " + t.VersionInvariantName(), e);
119          }
120        }
121        if (t.GetInterface(typeof(IDecomposer).FullName) != null) {
122          try {
123            Decomposers.Add((IDecomposer)Activator.CreateInstance(t, true));
124            Logger.Debug("discovered decomposer " + t.VersionInvariantName());
125          } catch (MissingMethodException e) {
126            Logger.Warn("Could not instantiate " + t.VersionInvariantName(), e);
127          } catch (ArgumentException e) {
128            Logger.Warn("Could not instantiate " + t.VersionInvariantName(), e);
129          }
130        }
131        if (t.GetInterface(typeof(IFormat).FullName) != null) {
132          try {
133            IFormat format = (IFormat)Activator.CreateInstance(t, true);
134            Formats.Add(format);
135            Logger.Debug(String.Format("discovered format {0} ({2}) with serial data {1}.",
136              format.Name,
137              format.SerialDataType,
138              t.VersionInvariantName()));
139          } catch (MissingMethodException e) {
140            Logger.Warn("Could not instantiate " + t.VersionInvariantName(), e);
141          } catch (ArgumentException e) {
142            Logger.Warn("Could not instantiate " + t.VersionInvariantName(), e);
143          }
144        }
145      }
146    }
147
148    public Configuration GetDefaultConfig(IFormat format) {
149      Dictionary<Type, IFormatter> formatterConfig = new Dictionary<Type, IFormatter>();
150      if (Formatters.ContainsKey(format.SerialDataType)) {
151        foreach (IFormatter f in Formatters[format.SerialDataType]) {
152          if (!formatterConfig.ContainsKey(f.SourceType))
153            formatterConfig.Add(f.SourceType, f);
154        }
155      } else {
156        Logger.Warn(String.Format(
157          "No formatters found for format {0} with serial data type {1}",
158          format.GetType().VersionInvariantName(),
159          format.SerialDataType.VersionInvariantName()));
160      }
161      return new Configuration(format, formatterConfig, Decomposers);
162    }
163
164    public Configuration GetConfiguration(IFormat format) {
165      if (customConfigurations.ContainsKey(format))
166        return customConfigurations[format];
167      return GetDefaultConfig(format);
168    }
169
170    public void DefineConfiguration(Configuration configuration) {
171      customConfigurations[configuration.Format] = configuration;
172      SaveSettings();
173    }
174
175  }
176
177}
Note: See TracBrowser for help on using the repository browser.