[9215] | 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 | }
|
---|