1 | using System;
|
---|
2 | using System.Collections.Generic;
|
---|
3 | using System.Linq;
|
---|
4 | using System.Text;
|
---|
5 | using System.IO;
|
---|
6 | using System.Xml;
|
---|
7 | using System.Globalization;
|
---|
8 | using System.Xml.Linq;
|
---|
9 |
|
---|
10 | namespace HeuristicLab.Services.Optimization.ControllerService {
|
---|
11 | public class ScenarioParser {
|
---|
12 | private static IList<Model.OptimizationScenario> scenarios;
|
---|
13 | private static object lockable = new object();
|
---|
14 |
|
---|
15 | public IList<Model.OptimizationScenario> Scenarios {
|
---|
16 | get {
|
---|
17 | if (scenarios == null) {
|
---|
18 | lock (lockable) {
|
---|
19 | if (scenarios == null) {
|
---|
20 | ParseScenarios();
|
---|
21 | }
|
---|
22 | }
|
---|
23 | }
|
---|
24 | return scenarios;
|
---|
25 | }
|
---|
26 | }
|
---|
27 |
|
---|
28 | public Model.OptimizationScenario GetByName(string name) {
|
---|
29 | foreach (var scen in Scenarios) {
|
---|
30 | if (scen.Name == name) {
|
---|
31 | return scen;
|
---|
32 | }
|
---|
33 | }
|
---|
34 | return null;
|
---|
35 | }
|
---|
36 |
|
---|
37 | // http://www.sascha-dittmann.de/post/Webseitenpfade-einer-Windows-Azure-Web-Rolle-bestimmen.aspx
|
---|
38 | private static IEnumerable<string> WebSiteDirectories {
|
---|
39 | get {
|
---|
40 | var roleRootDir = Environment.GetEnvironmentVariable("RdRoleRoot");
|
---|
41 | if (roleRootDir == null)
|
---|
42 | return Enumerable.Empty<string>();
|
---|
43 | XNamespace roleModelNs =
|
---|
44 | "http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition";
|
---|
45 | var roleModelDoc = XDocument.Load(Path.Combine(roleRootDir, "RoleModel.xml"));
|
---|
46 | if (roleModelDoc.Root == null)
|
---|
47 | return Enumerable.Empty<string>();
|
---|
48 |
|
---|
49 | var sites = roleModelDoc.Root.Element(roleModelNs + "Sites");
|
---|
50 | if (sites == null)
|
---|
51 | return Enumerable.Empty<string>();
|
---|
52 |
|
---|
53 | var siteElements = sites.Elements(roleModelNs + "Site");
|
---|
54 |
|
---|
55 | return
|
---|
56 | from siteElement in siteElements
|
---|
57 | where siteElement.Attribute("name") != null
|
---|
58 | && siteElement.Attribute("name").Value == "Web"
|
---|
59 | && siteElement.Attribute("physicalDirectory") != null
|
---|
60 | select Path.Combine(roleRootDir,
|
---|
61 | siteElement.Attribute("physicalDirectory").Value);
|
---|
62 | }
|
---|
63 | }
|
---|
64 |
|
---|
65 | private void ParseScenarios() {
|
---|
66 | var scens = new List<Model.OptimizationScenario>();
|
---|
67 | string path;
|
---|
68 | if (WebSiteDirectories.Count() != 0) {
|
---|
69 | path = WebSiteDirectories.FirstOrDefault() + @"\Mappings";
|
---|
70 | } else {
|
---|
71 | path = AppDomain.CurrentDomain.BaseDirectory + @"\Mappings";
|
---|
72 | }
|
---|
73 |
|
---|
74 | foreach (var file in Directory.EnumerateFiles(path, "*.xml")) {
|
---|
75 | var scenario = ParseScenario(file);
|
---|
76 | if (scenario != null)
|
---|
77 | scens.Add(scenario);
|
---|
78 | }
|
---|
79 |
|
---|
80 | scenarios = scens;
|
---|
81 | }
|
---|
82 |
|
---|
83 | private Model.OptimizationScenario ParseScenario(string filename) {
|
---|
84 | // Set the validation settings.
|
---|
85 | XmlReaderSettings settings = new XmlReaderSettings();
|
---|
86 | settings.ValidationType = ValidationType.Schema;
|
---|
87 | settings.Schemas.Add("urn:scenario-schema", AppDomain.CurrentDomain.BaseDirectory + @"\Mappings\scenario.xsd");
|
---|
88 | bool isErrorPresent = false;
|
---|
89 | settings.ValidationEventHandler += (sender, args) => {
|
---|
90 | Console.WriteLine(args.Message);
|
---|
91 | isErrorPresent = true;
|
---|
92 | };
|
---|
93 | Model.OptimizationScenario scenario = null;
|
---|
94 | using (var reader = XmlReader.Create(filename, settings)) {
|
---|
95 | while (!isErrorPresent && reader.Read()) {
|
---|
96 | if (reader.Name == "scenario" && reader.NodeType == XmlNodeType.Element) {
|
---|
97 | scenario = new Model.OptimizationScenario();
|
---|
98 | scenario.ProblemType = reader.GetAttribute("mapper");
|
---|
99 | scenario.ProblemType = reader.GetAttribute("algorithmType");
|
---|
100 | scenario.ProblemType = reader.GetAttribute("problemType");
|
---|
101 | }
|
---|
102 | else if (reader.Name == "name") {
|
---|
103 | scenario.Name = reader.ReadElementContentAsString();
|
---|
104 | }
|
---|
105 | else if (reader.Name == "problemParameters") {
|
---|
106 | IList<Model.Parameter> problemParameters = ParseParameters(reader);
|
---|
107 | foreach (var param in problemParameters)
|
---|
108 | scenario.InputParameters.Items.Add(param);
|
---|
109 | }
|
---|
110 | else if (reader.Name == "algorithmParameters") {
|
---|
111 | IList<Model.Parameter> algoParameters = ParseParameters(reader);
|
---|
112 | foreach (var param in algoParameters)
|
---|
113 | scenario.AlgorithmParameters.Items.Add(param);
|
---|
114 | }
|
---|
115 | }
|
---|
116 | }
|
---|
117 | if (isErrorPresent)
|
---|
118 | return null;
|
---|
119 | return scenario;
|
---|
120 | }
|
---|
121 |
|
---|
122 | struct ValueEntry {
|
---|
123 | public double v1;
|
---|
124 | public double v2;
|
---|
125 | };
|
---|
126 |
|
---|
127 | private void ParseDecimalMatrix(Model.DecimalMatrix matrix, XmlReader reader) {
|
---|
128 | IList<ValueEntry> ventries = new List<ValueEntry>();
|
---|
129 | while (reader.Read()) {
|
---|
130 | if (reader.Name == "param")
|
---|
131 | break;
|
---|
132 | if (reader.Name == "value") {
|
---|
133 | var val1 = Convert.ToDouble(reader.GetAttribute("v1"), CultureInfo.InvariantCulture.NumberFormat);
|
---|
134 | var val2 = Convert.ToDouble(reader.GetAttribute("v2"), CultureInfo.InvariantCulture.NumberFormat);
|
---|
135 | ventries.Add(new ValueEntry() { v1 = val1, v2 = val2 });
|
---|
136 | }
|
---|
137 | }
|
---|
138 | double[][] mat = new double[ventries.Count][];
|
---|
139 | int i=0;
|
---|
140 | foreach (var entry in ventries) {
|
---|
141 | mat[i] = new double[2];
|
---|
142 | mat[i][0] = entry.v1;
|
---|
143 | mat[i][1] = entry.v2;
|
---|
144 | i++;
|
---|
145 | }
|
---|
146 | matrix.Value = mat;
|
---|
147 | }
|
---|
148 |
|
---|
149 | private IList<Model.Parameter> ParseParameters(XmlReader reader) {
|
---|
150 | IList<Model.Parameter> parameters = new List<Model.Parameter>();
|
---|
151 | while (reader.Read()) {
|
---|
152 | if (reader.Name.EndsWith("Parameters"))
|
---|
153 | break;
|
---|
154 | // parse parameter
|
---|
155 | if (reader.Depth == 2 && reader.Name == "param" && reader.NodeType == XmlNodeType.Element) {
|
---|
156 | var param = new Model.Parameter();
|
---|
157 | var typeAtt = reader.GetAttribute("type");
|
---|
158 | param.Type = (Model.ParameterType)Enum.Parse(typeof(Model.ParameterType), typeAtt);
|
---|
159 | switch (param.Type) {
|
---|
160 | case Model.ParameterType.Boolean:
|
---|
161 | param.Value = new Model.BoolValue() { Name = reader.GetAttribute("name"), Value = Convert.ToBoolean(reader.GetAttribute("value")) };
|
---|
162 | break;
|
---|
163 | case Model.ParameterType.Integer:
|
---|
164 | case Model.ParameterType.Percent:
|
---|
165 | case Model.ParameterType.Decimal:
|
---|
166 | //TODO: Check which comma char is being used; enhance to use any
|
---|
167 | param.Value = new Model.DecimalValue() { Name = reader.GetAttribute("name"), Value = Convert.ToDouble(reader.GetAttribute("value"), CultureInfo.InvariantCulture.NumberFormat) };
|
---|
168 | break;
|
---|
169 | case Model.ParameterType.DecimalMatrix:
|
---|
170 | var decMatrix = new Model.DecimalMatrix() { Name = reader.GetAttribute("name") };
|
---|
171 | ParseDecimalMatrix(decMatrix, reader);
|
---|
172 | param.Value = decMatrix;
|
---|
173 | break;
|
---|
174 | case Model.ParameterType.DecimalVector:
|
---|
175 | var decVec = new Model.DecimalVector() { Name = reader.GetAttribute("name") };
|
---|
176 | ParseDecimalVector(decVec, reader);
|
---|
177 | param.Value = decVec;
|
---|
178 | break;
|
---|
179 | case Model.ParameterType.Type:
|
---|
180 | var type = new Model.TypeValue() { Name = reader.GetAttribute("name") };
|
---|
181 | ParseType(type, reader);
|
---|
182 | param.Value = type;
|
---|
183 | break;
|
---|
184 | case Model.ParameterType.String:
|
---|
185 | param.Value = new Model.StringValue() { Name = reader.GetAttribute("name"), Value = reader.GetAttribute("value") };
|
---|
186 | break;
|
---|
187 | default:
|
---|
188 | Console.WriteLine("Unhandled model type: " + param.Type);
|
---|
189 | break;
|
---|
190 | }
|
---|
191 | parameters.Add(param);
|
---|
192 | }
|
---|
193 | }
|
---|
194 | return parameters;
|
---|
195 | }
|
---|
196 |
|
---|
197 | private void ParseType(Model.TypeValue type, XmlReader reader) {
|
---|
198 | var choices = new List<string>();
|
---|
199 | string selected = null;
|
---|
200 | while (reader.Read()) {
|
---|
201 | if (reader.Name == "param")
|
---|
202 | break;
|
---|
203 | if (reader.Name == "choice") {
|
---|
204 | var choice = reader.GetAttribute("name");
|
---|
205 | if (reader.HasAttributes && Convert.ToBoolean(reader.GetAttribute("selected"))) {
|
---|
206 | selected = choice;
|
---|
207 | }
|
---|
208 | choices.Add(choice);
|
---|
209 | }
|
---|
210 | }
|
---|
211 | type.Options = choices.ToArray();
|
---|
212 | type.Value = selected;
|
---|
213 | }
|
---|
214 |
|
---|
215 | private void ParseDecimalVector(Model.DecimalVector decVec, XmlReader reader) {
|
---|
216 | var entries = new List<double>();
|
---|
217 | //IList<ValueEntry> ventries = new List<ValueEntry>();
|
---|
218 | while (reader.Read()) {
|
---|
219 | if (reader.Name == "param")
|
---|
220 | break;
|
---|
221 | if (reader.Name == "value") {
|
---|
222 | var val1 = Convert.ToDouble(reader.GetAttribute("v1"), CultureInfo.InvariantCulture.NumberFormat);
|
---|
223 | entries.Add(val1);
|
---|
224 | }
|
---|
225 | }
|
---|
226 | decVec.Value = entries.ToArray();
|
---|
227 | }
|
---|
228 | }
|
---|
229 | }
|
---|