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