SmartAPI
Open Source .NET RQL library for RedDot CMS / OpenText WSM Management Server
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Pages
StringEnumConverter.cs
Go to the documentation of this file.
1 ï»¿// SmartAPI - .Net programmatic access to RedDot servers
2 //
3 // Copyright (C) 2013 erminas GbR
4 //
5 // This program is free software: you can redistribute it and/or modify it
6 // under the terms of the GNU General Public License as published by the Free Software Foundation,
7 // either version 3 of the License, or (at your option) any later version.
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 // See the GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License along with this program.
14 // If not, see <http://www.gnu.org/licenses/>.
15 
16 using System;
17 using System.Collections.Generic;
18 using System.Linq;
19 using System.Reflection;
20 using System.Xml;
21 using erminas.SmartAPI.CMS.Project;
22 using erminas.SmartAPI.Exceptions;
23 using erminas.SmartAPI.Utils;
24 
25 namespace erminas.SmartAPI.CMS.Converter
26 {
27  [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
28  internal class EnumConversionHelperAttribute : Attribute
29  {
30  }
31 
32  internal static class StringEnumConversionRegistry
33  {
34  private static readonly Dictionary<Type, MethodInfo> FROM_STRING_METHODS = new Dictionary<Type, MethodInfo>();
35  private static readonly Dictionary<Type, MethodInfo> TO_STRING_METHODS = new Dictionary<Type, MethodInfo>();
36 
37  static StringEnumConversionRegistry()
38  {
39  var converters =
40  typeof (StringEnumConversionRegistry).Assembly.GetTypes()
41  .Where(
42  type =>
43  type.GetCustomAttributes(
44  typeof (EnumConversionHelperAttribute), false).Any());
45 
46  foreach (var curConverter in converters)
47  {
48  try
49  {
50  var toStringConversion = curConverter.GetMethod("ToRQLString",
51  BindingFlags.Static | BindingFlags.Public);
52 
53  var fromStringConversion =
54  curConverter.GetMethods(BindingFlags.Static | BindingFlags.Public)
55  .Single(
56  methodInfo =>
57  methodInfo.GetParameters()
58  .SingleOrDefault(info => info.ParameterType == typeof (string)) !=
59  null);
60 
61  //used as an assertion
62  toStringConversion.GetParameters()
63  .Single(info => info.ParameterType == fromStringConversion.ReturnType);
64 
65  if (toStringConversion.ReturnType != typeof (string))
66  {
67  throw new Exception(string.Format("Illegal return type for ToRQLString method in class {0}",
68  curConverter.Name));
69  }
70 
71  FROM_STRING_METHODS[fromStringConversion.ReturnType] = fromStringConversion;
72  TO_STRING_METHODS[fromStringConversion.ReturnType] = toStringConversion;
73  } catch (Exception e)
74  {
75  throw new SmartAPIInternalException(
76  string.Format("Class {0} is not a legal converter", curConverter.Name), e);
77  }
78  }
79  }
80 
81  public static T ConvertFromString<T>(string value)
82  {
83  try
84  {
85  return (T) FROM_STRING_METHODS[typeof (T)].Invoke(null, new object[] {value});
86  } catch (KeyNotFoundException)
87  {
88  throw new SmartAPIInternalException(string.Format("No converter registered for type {0}",
89  typeof (T).Name));
90  }
91  }
92 
93  public static string ConvertToRQLString<T>(T value) where T : struct, IConvertible
94  {
95  try
96  {
97  return (string) TO_STRING_METHODS[typeof (T)].Invoke(null, new object[] {value});
98  } catch (KeyNotFoundException)
99  {
100  throw new SmartAPIInternalException(string.Format("No converter registered for type {0}",
101  typeof (T).Name));
102  }
103  }
104  }
105 
106  internal class StringEnumConverter<T> : IAttributeConverter<T> where T : struct, IConvertible
107  {
108  public T ConvertFrom(IProjectObject parent, XmlElement element, RedDotAttribute attribute)
109  {
110  var strValue = element.GetAttributeValue(attribute.ElementName);
111  return StringEnumConversionRegistry.ConvertFromString<T>(strValue);
112  }
113 
114  public bool IsReadOnly { get; set; }
115 
116  public void WriteTo(IProjectObject parent, IXmlReadWriteWrapper writeElement, RedDotAttribute attribute, T value)
117  {
118  writeElement.SetAttributeValue(attribute.ElementName, StringEnumConversionRegistry.ConvertToRQLString(value));
119  }
120  }
121 }