#region License Information
/* HeuristicLab
* Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
*
* This file is part of HeuristicLab.
*
* HeuristicLab is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* HeuristicLab is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with HeuristicLab. If not, see .
*/
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using HeuristicLab.Clients.Common;
using HeuristicLab.Collections;
using HeuristicLab.Common;
using HeuristicLab.Core;
using HeuristicLab.Data;
using HeuristicLab.Optimization;
using HeuristicLab.PluginInfrastructure;
namespace HeuristicLab.Clients.OKB {
[Item("OKBClient", "Client for accessing the OKB.")]
public sealed class OKBClient : IContent {
private static OKBClient instance;
public static OKBClient Instance {
get {
if (instance == null) instance = new OKBClient();
return instance;
}
}
#region Properties
private ItemCollection platforms;
public ItemCollection Platforms {
get { return platforms; }
}
private ItemCollection dataTypes;
public ItemCollection DataTypes {
get { return dataTypes; }
}
private IEnumerable users;
public IEnumerable Users {
get { return users; }
}
private ItemCollection algorithmClasses;
public ItemCollection AlgorithmClasses {
get { return algorithmClasses; }
}
private ItemCollection algorithms;
public ItemCollection Algorithms {
get { return algorithms; }
}
private ItemCollection problemClasses;
public ItemCollection ProblemClasses {
get { return problemClasses; }
}
private ItemCollection problems;
public ItemCollection Problems {
get { return problems; }
}
#endregion
private OKBClient() {
platforms = new ItemCollection();
platforms.ItemsRemoved += new CollectionItemsChangedEventHandler(platforms_ItemsRemoved);
dataTypes = new ItemCollection();
dataTypes.ItemsRemoved += new CollectionItemsChangedEventHandler(dataTypes_ItemsRemoved);
algorithmClasses = new ItemCollection();
algorithmClasses.ItemsRemoved += new CollectionItemsChangedEventHandler(algorithmClasses_ItemsRemoved);
algorithms = new ItemCollection();
algorithms.ItemsRemoved += new CollectionItemsChangedEventHandler(algorithms_ItemsRemoved);
problemClasses = new ItemCollection();
problemClasses.ItemsRemoved += new CollectionItemsChangedEventHandler(problemClasses_ItemsRemoved);
problems = new ItemCollection();
problems.ItemsRemoved += new CollectionItemsChangedEventHandler(problems_ItemsRemoved);
}
#region Refresh
public void Refresh() {
OnRefreshing();
platforms.Clear();
dataTypes.Clear();
algorithmClasses.Clear();
algorithms.Clear();
problemClasses.Clear();
problems.Clear();
var call = new Func(delegate() {
try {
platforms.AddRange(CallAdminService(s => s.GetPlatforms()).OrderBy(x => x.Name));
dataTypes.AddRange(CallAdminService(s => s.GetDataTypes()).OrderBy(x => x.Name));
users = CallAuthenticationService(s => s.GetUsers()).OrderBy(x => x.Name);
algorithmClasses.AddRange(CallAdminService(s => s.GetAlgorithmClasses()).OrderBy(x => x.Name));
algorithms.AddRange(CallAdminService(s => s.GetAlgorithms()).OrderBy(x => x.Name));
problemClasses.AddRange(CallAdminService(s => s.GetProblemClasses()).OrderBy(x => x.Name));
problems.AddRange(CallAdminService(s => s.GetProblems()).OrderBy(x => x.Name));
return null;
}
catch (Exception ex) {
return ex;
}
});
call.BeginInvoke(delegate(IAsyncResult result) {
Exception ex = call.EndInvoke(result);
if (ex != null) ErrorHandling.ShowErrorDialog("Refresh failed.", ex);
OnRefreshed();
}, null);
}
#endregion
#region Store
public bool Store(IOKBItem item) {
try {
if (item.Id == 0) {
if (item is Platform)
item.Id = CallAdminService(s => s.AddPlatform((Platform)item));
else if (item is DataType)
item.Id = CallAdminService(s => s.AddDataType((DataType)item));
else if (item is AlgorithmClass)
item.Id = CallAdminService(s => s.AddAlgorithmClass((AlgorithmClass)item));
else if (item is Algorithm)
item.Id = CallAdminService(s => s.AddAlgorithm((Algorithm)item));
else if (item is AlgorithmParameter)
item.Id = CallAdminService(s => s.AddAlgorithmParameter((AlgorithmParameter)item));
else if (item is ProblemClass)
item.Id = CallAdminService(s => s.AddProblemClass((ProblemClass)item));
else if (item is Problem)
item.Id = CallAdminService(s => s.AddProblem((Problem)item));
else if (item is ProblemParameter)
item.Id = CallAdminService(s => s.AddProblemParameter((ProblemParameter)item));
else if (item is Result)
item.Id = CallAdminService(s => s.AddResult((Result)item));
else if (item is Experiment)
item.Id = CallAdminService(s => s.AddExperiment((Experiment)item));
else if (item is Run)
item.Id = CallAdminService(s => s.AddRun((Run)item));
} else {
if (item is Platform)
CallAdminService(s => s.UpdatePlatform((Platform)item));
else if (item is DataType)
CallAdminService(s => s.UpdateDataType((DataType)item));
else if (item is AlgorithmClass)
CallAdminService(s => s.UpdateAlgorithmClass((AlgorithmClass)item));
else if (item is Algorithm)
CallAdminService(s => s.UpdateAlgorithm((Algorithm)item));
else if (item is AlgorithmParameter)
CallAdminService(s => s.UpdateAlgorithmParameter((AlgorithmParameter)item));
else if (item is ProblemClass)
CallAdminService(s => s.UpdateProblemClass((ProblemClass)item));
else if (item is Problem)
CallAdminService(s => s.UpdateProblem((Problem)item));
else if (item is ProblemParameter)
CallAdminService(s => s.UpdateProblemParameter((ProblemParameter)item));
else if (item is Result)
CallAdminService(s => s.UpdateResult((Result)item));
else if (item is Experiment)
item.Id = CallAdminService(s => s.AddExperiment((Experiment)item));
else if (item is Run)
item.Id = CallAdminService(s => s.AddRun((Run)item));
}
return true;
}
catch (Exception ex) {
ErrorHandling.ShowErrorDialog("Store failed.", ex);
return false;
}
}
#endregion
#region DataType Methods
public DataType ConvertToDataType(Type type) {
DataType dataType = DataTypes.FirstOrDefault(x => x.Name == type.AssemblyQualifiedName);
if (dataType == null) {
dataType = new DataType();
dataType.Name = type.AssemblyQualifiedName;
dataType.PlatformId = Platforms.FirstOrDefault(x => x.Name == "HeuristicLab 3.3").Id;
if (typeof(BoolValue).IsAssignableFrom(type))
dataType.SqlName = "bit";
else if (typeof(IntValue).IsAssignableFrom(type))
dataType.SqlName = "bigint";
else if (typeof(DoubleValue).IsAssignableFrom(type))
dataType.SqlName = "float";
else if (typeof(StringValue).IsAssignableFrom(type) || typeof(IStringConvertibleValue).IsAssignableFrom(type))
dataType.SqlName = "nvarchar";
else
dataType.SqlName = "varbinary";
dataType.Store();
DataTypes.Add(dataType);
}
return dataType;
}
#endregion
#region Algorithm Methods
public Guid[] GetAlgorithmUsers(long algorithmId) {
try {
return CallAdminService(s => s.GetAlgorithmUsers(algorithmId));
}
catch (Exception ex) {
ErrorHandling.ShowErrorDialog("Refresh authorized algorithm users failed.", ex);
return null;
}
}
public bool UpdateAlgorithmUsers(long algorithmId, Guid[] users) {
try {
CallAdminService(s => s.UpdateAlgorithmUsers(algorithmId, users));
return true;
}
catch (Exception ex) {
ErrorHandling.ShowErrorDialog("Update authorized algorithm users failed.", ex);
return false;
}
}
public AlgorithmData GetAlgorithmData(long algorithmId) {
try {
return CallAdminService(s => s.GetAlgorithmData(algorithmId));
}
catch (Exception ex) {
ErrorHandling.ShowErrorDialog("Refresh algorithm data failed.", ex);
return null;
}
}
public bool UpdateAlgorithmData(AlgorithmData algorithmData) {
try {
CallAdminService(s => s.UpdateAlgorithmData(algorithmData));
return true;
}
catch (Exception ex) {
ErrorHandling.ShowErrorDialog("Update algorithm data failed.", ex);
return false;
}
}
public ItemCollection GetAlgorithmParameters(long algorithmId) {
try {
ItemCollection parameters = new ItemCollection();
parameters.AddRange(CallAdminService(s => s.GetAlgorithmParameters(algorithmId)).OrderBy(x => x.Name));
return parameters;
}
catch (Exception ex) {
ErrorHandling.ShowErrorDialog("Refresh algorithm parameters failed.", ex);
return null;
}
}
public ItemCollection GetResults(long algorithmId) {
try {
ItemCollection results = new ItemCollection();
results.AddRange(CallAdminService(s => s.GetResults(algorithmId)).OrderBy(x => x.Name));
return results;
}
catch (Exception ex) {
ErrorHandling.ShowErrorDialog("Refresh results failed.", ex);
return null;
}
}
#endregion
#region Problem Methods
public Guid[] GetProblemUsers(long problemId) {
try {
return CallAdminService(s => s.GetProblemUsers(problemId));
}
catch (Exception ex) {
ErrorHandling.ShowErrorDialog("Refresh authorized problem users failed.", ex);
return null;
}
}
public bool UpdateProblemUsers(long problemId, Guid[] users) {
try {
CallAdminService(s => s.UpdateProblemUsers(problemId, users));
return true;
}
catch (Exception ex) {
ErrorHandling.ShowErrorDialog("Update authorized problem users failed.", ex);
return false;
}
}
public ProblemData GetProblemData(long problemId) {
try {
return CallAdminService(s => s.GetProblemData(problemId));
}
catch (Exception ex) {
ErrorHandling.ShowErrorDialog("Refresh problem data failed.", ex);
return null;
}
}
public bool UpdateProblemData(ProblemData problemData) {
try {
CallAdminService(s => s.UpdateProblemData(problemData));
return true;
}
catch (Exception ex) {
ErrorHandling.ShowErrorDialog("Update problem data failed.", ex);
return false;
}
}
public ItemCollection GetProblemParameters(long problemId) {
try {
ItemCollection parameters = new ItemCollection();
parameters.AddRange(CallAdminService(s => s.GetProblemParameters(problemId)).OrderBy(x => x.Name));
return parameters;
}
catch (Exception ex) {
ErrorHandling.ShowErrorDialog("Refresh problem parameters failed.", ex);
return null;
}
}
#endregion
#region Run Methods
public bool AddRun(long algorithmId, long problemId, HeuristicLab.Optimization.Run run) {
try {
IAlgorithm algorithm = run.Algorithm;
IProblem problem = algorithm.Problem;
ItemCollection algorithmParameters = GetAlgorithmParameters(algorithmId);
List algorithmParameterValues = CollectAlgorithmParameterValues(algorithmId, algorithmParameters, algorithm, "");
ItemCollection problemParameters = GetProblemParameters(problemId);
List problemParameterValues = CollectProblemParamterValues(problemId, problemParameters, problem, "");
ItemCollection results = GetResults(algorithmId);
List resultValues = CollectResultValues(algorithmId, results, algorithm);
Experiment exp = new Experiment();
exp.AlgorithmId = algorithmId;
exp.ProblemId = problemId;
exp.AlgorithmParameterValues = algorithmParameterValues.ToArray();
exp.ProblemParameterValues = problemParameterValues.ToArray();
exp.Store();
Run r = new Run();
r.ExperimentId = exp.Id;
r.ClientId = Guid.NewGuid();
r.FinishedDate = DateTime.Now;
r.RandomSeed = ((IntValue)((IValueParameter)run.Parameters["Seed"]).Value).Value;
r.ResultValues = resultValues.ToArray();
r.Store();
return true;
}
catch (Exception ex) {
ErrorHandling.ShowErrorDialog("Store run failed.", ex);
return false;
}
}
private List CollectAlgorithmParameterValues(long algorithmId, ItemCollection parameters, IParameterizedItem item, string prefix) {
List values = new List();
foreach (IValueParameter param in item.Parameters.OfType()) {
if (param.GetsCollected && (param.Value != null)) {
AlgorithmParameter p = parameters.FirstOrDefault(x => x.Name == prefix + param.Name);
if (p == null) {
p = new AlgorithmParameter();
p.Name = prefix + param.Name;
p.Alias = prefix + param.Name;
p.Description = param.Description;
p.AlgorithmId = algorithmId;
p.DataTypeId = ConvertToDataType(param.DataType).Id;
p.Store();
parameters.Add(p);
}
AlgorithmParameterValue value = null;
// TODO
value.AlgorithmParameterId = p.Id;
value.DataTypeId = ConvertToDataType(param.Value.GetType()).Id;
}
if (param.Value is IParameterizedItem)
values.AddRange(CollectAlgorithmParameterValues(algorithmId, parameters, (IParameterizedItem)param.Value, (string.IsNullOrEmpty(prefix) ? param.Name : prefix + param.Name) + "."));
}
return values;
}
private List CollectProblemParamterValues(long problemId, ItemCollection parameters, IParameterizedItem item, string prefix) {
List values = new List();
foreach (IValueParameter param in item.Parameters.OfType()) {
if (param.GetsCollected && (param.Value != null) && (parameters.FirstOrDefault(x => x.Name == prefix + param.Name) == null)) {
ProblemParameter p = new ProblemParameter();
p.Name = prefix + param.Name;
p.Alias = prefix + param.Name;
p.Description = param.Description;
p.ProblemId = problemId;
p.DataTypeId = ConvertToDataType(param.DataType).Id;
p.Store();
parameters.Add(p);
}
if (param.Value is IParameterizedItem)
values.AddRange(CollectProblemParamterValues(problemId, parameters, (IParameterizedItem)param.Value, (string.IsNullOrEmpty(prefix) ? param.Name : prefix + param.Name) + "."));
}
return values;
}
private List CollectResultValues(long algorithmId, ItemCollection results, IAlgorithm algorithm) {
List values = new List();
foreach (IResult result in algorithm.Results) {
if ((result.Value != null) && (results.FirstOrDefault(x => x.Name == result.Name) == null)) {
Result r = new Result();
r.Name = result.Name;
r.Alias = result.Name;
r.Description = result.Description;
r.AlgorithmId = algorithmId;
r.DataTypeId = ConvertToDataType(result.DataType).Id;
r.Store();
results.Add(r);
}
}
return values;
}
#endregion
#region Events
public event EventHandler Refreshing;
private void OnRefreshing() {
EventHandler handler = Refreshing;
if (handler != null) handler(this, EventArgs.Empty);
}
public event EventHandler Refreshed;
private void OnRefreshed() {
EventHandler handler = Refreshed;
if (handler != null) handler(this, EventArgs.Empty);
}
private void platforms_ItemsRemoved(object sender, CollectionItemsChangedEventArgs e) {
try {
foreach (Platform p in e.Items)
CallAdminService(s => s.DeletePlatform(p.Id));
}
catch (Exception ex) {
ErrorHandling.ShowErrorDialog("Delete failed.", ex);
}
}
private void dataTypes_ItemsRemoved(object sender, CollectionItemsChangedEventArgs e) {
try {
foreach (DataType d in e.Items)
CallAdminService(s => s.DeleteDataType(d.Id));
}
catch (Exception ex) {
ErrorHandling.ShowErrorDialog("Delete failed.", ex);
}
}
private void algorithmClasses_ItemsRemoved(object sender, CollectionItemsChangedEventArgs e) {
try {
foreach (AlgorithmClass a in e.Items)
CallAdminService(s => s.DeleteAlgorithmClass(a.Id));
}
catch (Exception ex) {
ErrorHandling.ShowErrorDialog("Delete failed.", ex);
}
}
private void algorithms_ItemsRemoved(object sender, CollectionItemsChangedEventArgs e) {
try {
foreach (Algorithm a in e.Items)
CallAdminService(s => s.DeleteAlgorithm(a.Id));
}
catch (Exception ex) {
ErrorHandling.ShowErrorDialog("Delete failed.", ex);
}
}
private void problemClasses_ItemsRemoved(object sender, CollectionItemsChangedEventArgs e) {
try {
foreach (ProblemClass p in e.Items)
CallAdminService(s => s.DeleteProblemClass(p.Id));
}
catch (Exception ex) {
ErrorHandling.ShowErrorDialog("Delete failed.", ex);
}
}
private void problems_ItemsRemoved(object sender, CollectionItemsChangedEventArgs e) {
try {
foreach (Problem p in e.Items)
CallAdminService(s => s.DeleteProblem(p.Id));
}
catch (Exception ex) {
ErrorHandling.ShowErrorDialog("Delete failed.", ex);
}
}
#endregion
#region Helpers
private void CallAdminService(Action call) {
OKBServiceClient client = ClientFactory.CreateClient();
try {
call(client);
}
finally {
try {
client.Close();
}
catch (Exception) {
client.Abort();
}
}
}
private T CallAdminService(Func call) {
OKBServiceClient client = ClientFactory.CreateClient();
try {
return call(client);
}
finally {
try {
client.Close();
}
catch (Exception) {
client.Abort();
}
}
}
private T CallAuthenticationService(Func call) {
AuthenticationServiceClient client = ClientFactory.CreateClient();
try {
return call(client);
}
finally {
try {
client.Close();
}
catch (Exception) {
client.Abort();
}
}
}
#endregion
}
}