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