~halega/+junk/sqlinstaller

« back to all changes in this revision

Viewing changes to SQLInstaller.Core/Arguments.cs

  • Committer: sk
  • Date: 2011-09-10 05:32:36 UTC
  • Revision ID: halega@halega.com-20110910053236-1877r3p0k4a64bgx
Tags: 1.2.2
1.2.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//-----------------------------------------------------------------------
 
2
// <copyright file="Arguments.cs" company="JHOB Technologies, LLC">
 
3
//     Copyright © JHOB Technologies, LLC. All rights reserved.
 
4
// </copyright>
 
5
// <license>Microsoft Public License</license>
 
6
// <author>Brian Schloz</author>
 
7
//-----------------------------------------------------------------------
 
8
namespace SQLInstaller.Core
 
9
{
 
10
    using System;
 
11
    using System.Collections.Generic;
 
12
    using System.Collections.ObjectModel;
 
13
    using System.ComponentModel;
 
14
    using System.ComponentModel.DataAnnotations;
 
15
    using System.Text;
 
16
 
 
17
    public sealed class Arguments<T> where T : new()
 
18
    {
 
19
        private Collection<ValidationResult> validationResults;
 
20
 
 
21
        public Arguments(IEnumerable<string> args, T instance)
 
22
        {
 
23
            this.OriginalArgs = args;
 
24
            this.Instance = instance;
 
25
            this.validationResults = new Collection<ValidationResult>();
 
26
 
 
27
            this.Parse();
 
28
        }
 
29
 
 
30
        public Arguments(IEnumerable<string> args)
 
31
            : this(args, new T())
 
32
        {
 
33
        }
 
34
 
 
35
        public IEnumerable<string> OriginalArgs { get; private set; }
 
36
 
 
37
        public T Instance { get; private set; }
 
38
 
 
39
        public bool IsValid
 
40
        {
 
41
            get { return this.validationResults.Count == 0; }
 
42
        }
 
43
 
 
44
        public string ValidationErrors
 
45
        {
 
46
            get
 
47
            {
 
48
                StringBuilder error = new StringBuilder();
 
49
                foreach (ValidationResult result in this.validationResults)
 
50
                {
 
51
                    error.Append(result.ErrorMessage);
 
52
                    error.Append(" ");
 
53
                }
 
54
 
 
55
                return error.ToString();
 
56
            }
 
57
        }
 
58
 
 
59
        private void Parse()
 
60
        {
 
61
            PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(this.Instance);
 
62
 
 
63
            foreach (string arg in this.OriginalArgs)
 
64
            {
 
65
                if (arg.Length <= 1 || !arg.StartsWith("/", StringComparison.InvariantCulture))
 
66
                {
 
67
                    continue;
 
68
                }
 
69
 
 
70
                string key;
 
71
                string value = string.Empty;
 
72
 
 
73
                int equalIdx = arg.IndexOf('=');
 
74
                if (equalIdx > 0)
 
75
                {
 
76
                    key = arg.Substring(1, equalIdx - 1);
 
77
                    value = arg.Substring(equalIdx + 1);
 
78
                }
 
79
                else
 
80
                {
 
81
                    key = arg.Substring(1);
 
82
                }
 
83
 
 
84
                PropertyDescriptor property = this.FindProperty(key, properties);
 
85
 
 
86
                if (property != null)
 
87
                {
 
88
                    if (property.PropertyType == typeof(bool) || property.PropertyType == typeof(bool?))
 
89
                    {
 
90
                        property.SetValue(this.Instance, true);
 
91
                    }
 
92
                    else
 
93
                    {
 
94
                        TypeConverter typeConverter = TypeDescriptor.GetConverter(property.PropertyType);
 
95
                        if (typeConverter != null && typeConverter.CanConvertFrom(typeof(string)))
 
96
                        {
 
97
                            property.SetValue(this.Instance, typeConverter.ConvertFromInvariantString(value));
 
98
                        }
 
99
                    }
 
100
                }
 
101
            }
 
102
 
 
103
            Validator.TryValidateObject(this.Instance, new ValidationContext(this.Instance, null, null), this.validationResults, true);
 
104
        }
 
105
 
 
106
        /// <summary>
 
107
        /// Find an unambiguous matching property for the given argument.
 
108
        /// </summary>
 
109
        /// <param name="keyName"></param>
 
110
        /// <param name="properties"></param>
 
111
        /// <returns></returns>
 
112
        private PropertyDescriptor FindProperty(string keyName, PropertyDescriptorCollection properties)
 
113
        {
 
114
            List<PropertyDescriptor> matches = new List<PropertyDescriptor>();
 
115
            foreach (PropertyDescriptor prop in properties)
 
116
            {
 
117
                // Ignore property hacks for xml serialization.
 
118
                if (prop.Name.EndsWith("Specified", StringComparison.OrdinalIgnoreCase))
 
119
                {
 
120
                    continue;
 
121
                }
 
122
 
 
123
                // An exact match on the argument/property will always succeed. Otherwise, do a partial match.
 
124
                // E.g. Two arguments - Foo and FooBar. /Foo will succeed /FooB will succeed. /Fo or /F will fail (ambiguous).
 
125
                if (string.Compare(prop.Name, keyName, StringComparison.OrdinalIgnoreCase) == 0)
 
126
                {
 
127
                    matches.Clear();
 
128
                    matches.Add(prop);
 
129
                    break;
 
130
                }
 
131
                else if (keyName.Length == 1)
 
132
                {
 
133
                    if (prop.Name.StartsWith(keyName, StringComparison.OrdinalIgnoreCase))
 
134
                    {
 
135
                        matches.Add(prop);
 
136
                    }
 
137
                }
 
138
                else if (prop.Name.IndexOf(keyName, StringComparison.OrdinalIgnoreCase) >= 0)
 
139
                {
 
140
                    matches.Add(prop);
 
141
                }
 
142
            }
 
143
 
 
144
            if (matches.Count == 1)
 
145
            {
 
146
                return matches[0];
 
147
            }
 
148
            else
 
149
            {
 
150
                return null;
 
151
            }
 
152
        }
 
153
    }
 
154
}