#region License Information /* HeuristicLab * Copyright (C) 2002-2015 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.Data.Linq; using System.Linq; using System.ServiceModel; using HeuristicLab.Services.Access; using HeuristicLab.Services.OKB.DataAccess; using HeuristicLab.Services.OKB.Query.DataTransfer; using HeuristicLab.Services.OKB.Query.Filters; namespace HeuristicLab.Services.OKB.Query { /// /// Implementation of the OKB query service (interface ). /// [ServiceBehavior(IncludeExceptionDetailInFaults = true)] public class QueryService : IQueryService { IRoleVerifier roleVerifier = AccessServiceLocator.Instance.RoleVerifier; IUserManager userManager = AccessServiceLocator.Instance.UserManager; public IEnumerable GetFilters() { List filters = new List(); using (OKBDataContext okb = new OKBDataContext()) { #region Run Filters filters.Add(new OrdinalComparisonDateTimeFilter(typeof(RunCreatedDateFilter).AssemblyQualifiedName, "Run Created Date")); filters.Add(new StringComparisonFilter(typeof(RunUserNameFilter).AssemblyQualifiedName, "Run User Name")); filters.Add(new StringComparisonFilter(typeof(RunClientNameFilter).AssemblyQualifiedName, "Run Client Name")); #endregion #region Parameter Filters filters.Add(new StringComparisonAvailableValuesFilter( typeof(ValueNameFilter).AssemblyQualifiedName, "Parameter Name", okb.ValueNames.Where(x => x.Category == ValueNameCategory.Parameter).Select(x => x.Name).Distinct().ToArray() )); foreach (string name in okb.ValueNames.Where(x => (x.Category == ValueNameCategory.Parameter) && (x.Type == ValueNameType.Binary)).Select(x => x.Name).Distinct()) filters.Add(new NameStringComparisonAvailableValuesFilter( typeof(ValueDataTypeNameFilter).AssemblyQualifiedName, "Parameter " + name + " Value Data Type Name", name, okb.Values.Where(x => (x.ValueName.Name == name) && (x.ValueName.Category == ValueNameCategory.Parameter) && (x.ValueName.Type == ValueNameType.Binary)).Select(x => x.DataType.Name).Distinct().ToArray() )); foreach (string name in okb.ValueNames.Where(x => (x.Category == ValueNameCategory.Parameter) && (x.Type == ValueNameType.Bool)).Select(x => x.Name).Distinct()) filters.Add(new NameEqualityComparisonBoolFilter( typeof(BoolValueFilter).AssemblyQualifiedName, "Parameter " + name + " Value", name )); foreach (string name in okb.ValueNames.Where(x => (x.Category == ValueNameCategory.Parameter) && (x.Type == ValueNameType.Int)).Select(x => x.Name).Distinct()) filters.Add(new NameOrdinalComparisonIntFilter( typeof(IntValueFilter).AssemblyQualifiedName, "Parameter " + name + " Value", name )); foreach (string name in okb.ValueNames.Where(x => (x.Category == ValueNameCategory.Parameter) && (x.Type == ValueNameType.Long)).Select(x => x.Name).Distinct()) filters.Add(new NameOrdinalComparisonLongFilter( typeof(LongValueFilter).AssemblyQualifiedName, "Parameter " + name + " Value", name )); foreach (string name in okb.ValueNames.Where(x => (x.Category == ValueNameCategory.Parameter) && (x.Type == ValueNameType.TimeSpan)).Select(x => x.Name).Distinct()) filters.Add(new NameOrdinalComparisonTimeSpanFilter( typeof(TimeSpanValueFilter).AssemblyQualifiedName, "Parameter " + name + " Value", name )); foreach (string name in okb.ValueNames.Where(x => (x.Category == ValueNameCategory.Parameter) && (x.Type == ValueNameType.Float)).Select(x => x.Name).Distinct()) filters.Add(new NameOrdinalComparisonFloatFilter( typeof(FloatValueFilter).AssemblyQualifiedName, "Parameter " + name + " Value", name )); foreach (string name in okb.ValueNames.Where(x => (x.Category == ValueNameCategory.Parameter) && (x.Type == ValueNameType.Double)).Select(x => x.Name).Distinct()) filters.Add(new NameOrdinalComparisonDoubleFilter( typeof(DoubleValueFilter).AssemblyQualifiedName, "Parameter " + name + " Value", name )); foreach (string name in okb.ValueNames.Where(x => (x.Category == ValueNameCategory.Parameter) && (x.Type == ValueNameType.Percent)).Select(x => x.Name).Distinct()) filters.Add(new NameOrdinalComparisonPercentFilter( typeof(PercentValueFilter).AssemblyQualifiedName, "Parameter " + name + " Value", name )); foreach (string name in okb.ValueNames.Where(x => (x.Category == ValueNameCategory.Parameter) && (x.Type == ValueNameType.String)).Select(x => x.Name).Distinct()) filters.Add(new NameStringComparisonFilter( typeof(StringValueFilter).AssemblyQualifiedName, "Parameter " + name + " Value", name )); foreach (string name in okb.ValueNames.Where(x => (x.Category == ValueNameCategory.Parameter) && (x.Type == ValueNameType.Binary)).Select(x => x.Name).Distinct()) filters.Add(new NameEqualityComparisonByteArrayFilter( typeof(BinaryValueFilter).AssemblyQualifiedName, "Parameter " + name + " Value", name )); #endregion #region Result Filters filters.Add(new StringComparisonAvailableValuesFilter( typeof(ValueNameFilter).AssemblyQualifiedName, "Result Name", okb.ValueNames.Where(x => x.Category == ValueNameCategory.Result).Select(x => x.Name).Distinct().ToArray() )); foreach (string name in okb.ValueNames.Where(x => (x.Category == ValueNameCategory.Result) && (x.Type == ValueNameType.Binary)).Select(x => x.Name).Distinct()) filters.Add(new NameStringComparisonAvailableValuesFilter( typeof(ValueDataTypeNameFilter).AssemblyQualifiedName, "Result " + name + " Value Data Type Name", name, okb.Values.Where(x => (x.ValueName.Name == name) && (x.ValueName.Category == ValueNameCategory.Result) && (x.ValueName.Type == ValueNameType.Binary)).Select(x => x.DataType.Name).Distinct().ToArray() )); foreach (string name in okb.ValueNames.Where(x => (x.Category == ValueNameCategory.Result) && (x.Type == ValueNameType.Bool)).Select(x => x.Name).Distinct()) filters.Add(new NameEqualityComparisonBoolFilter( typeof(BoolValueFilter).AssemblyQualifiedName, "Result " + name + " Value", name )); foreach (string name in okb.ValueNames.Where(x => (x.Category == ValueNameCategory.Result) && (x.Type == ValueNameType.Int)).Select(x => x.Name).Distinct()) filters.Add(new NameOrdinalComparisonIntFilter( typeof(IntValueFilter).AssemblyQualifiedName, "Result " + name + " Value", name )); foreach (string name in okb.ValueNames.Where(x => (x.Category == ValueNameCategory.Result) && (x.Type == ValueNameType.Long)).Select(x => x.Name).Distinct()) filters.Add(new NameOrdinalComparisonLongFilter( typeof(LongValueFilter).AssemblyQualifiedName, "Result " + name + " Value", name )); foreach (string name in okb.ValueNames.Where(x => (x.Category == ValueNameCategory.Result) && (x.Type == ValueNameType.TimeSpan)).Select(x => x.Name).Distinct()) filters.Add(new NameOrdinalComparisonTimeSpanFilter( typeof(TimeSpanValueFilter).AssemblyQualifiedName, "Result " + name + " Value", name )); foreach (string name in okb.ValueNames.Where(x => (x.Category == ValueNameCategory.Result) && (x.Type == ValueNameType.Float)).Select(x => x.Name).Distinct()) filters.Add(new NameOrdinalComparisonFloatFilter( typeof(FloatValueFilter).AssemblyQualifiedName, "Result " + name + " Value", name )); foreach (string name in okb.ValueNames.Where(x => (x.Category == ValueNameCategory.Result) && (x.Type == ValueNameType.Double)).Select(x => x.Name).Distinct()) filters.Add(new NameOrdinalComparisonDoubleFilter( typeof(DoubleValueFilter).AssemblyQualifiedName, "Result " + name + " Value", name )); foreach (string name in okb.ValueNames.Where(x => (x.Category == ValueNameCategory.Result) && (x.Type == ValueNameType.Percent)).Select(x => x.Name).Distinct()) filters.Add(new NameOrdinalComparisonPercentFilter( typeof(PercentValueFilter).AssemblyQualifiedName, "Result " + name + " Value", name )); foreach (string name in okb.ValueNames.Where(x => (x.Category == ValueNameCategory.Result) && (x.Type == ValueNameType.String)).Select(x => x.Name).Distinct()) filters.Add(new NameStringComparisonFilter( typeof(StringValueFilter).AssemblyQualifiedName, "Result " + name + " Value", name )); foreach (string name in okb.ValueNames.Where(x => (x.Category == ValueNameCategory.Result) && (x.Type == ValueNameType.Binary)).Select(x => x.Name).Distinct()) filters.Add(new NameEqualityComparisonByteArrayFilter( typeof(BinaryValueFilter).AssemblyQualifiedName, "Result " + name + " Value", name )); #endregion #region Algorithm Filters filters.Add(new StringComparisonAvailableValuesFilter( typeof(AlgorithmNameFilter).AssemblyQualifiedName, "Algorithm Name", okb.Algorithms.Select(x => x.Name).Distinct().ToArray() )); filters.Add(new StringComparisonAvailableValuesFilter( typeof(AlgorithmClassNameFilter).AssemblyQualifiedName, "Algorithm Class Name", okb.AlgorithmClasses.Select(x => x.Name).Distinct().ToArray() )); filters.Add(new StringComparisonAvailableValuesFilter( typeof(AlgorithmPlatformNameFilter).AssemblyQualifiedName, "Algorithm Platform Name", okb.Platforms.Select(x => x.Name).Distinct().ToArray() )); filters.Add(new StringComparisonAvailableValuesFilter( typeof(AlgorithmDataTypeNameFilter).AssemblyQualifiedName, "Algorithm Data Type Name", okb.Algorithms.Select(x => x.DataType.Name).Distinct().ToArray() )); #endregion #region Problem Filters filters.Add(new StringComparisonAvailableValuesFilter( typeof(ProblemNameFilter).AssemblyQualifiedName, "Problem Name", okb.Problems.Select(x => x.Name).Distinct().ToArray() )); filters.Add(new StringComparisonAvailableValuesFilter( typeof(ProblemClassNameFilter).AssemblyQualifiedName, "Problem Class Name", okb.ProblemClasses.Select(x => x.Name).Distinct().ToArray() )); filters.Add(new StringComparisonAvailableValuesFilter( typeof(ProblemPlatformNameFilter).AssemblyQualifiedName, "Problem Platform Name", okb.Platforms.Select(x => x.Name).Distinct().ToArray() )); filters.Add(new StringComparisonAvailableValuesFilter( typeof(ProblemDataTypeNameFilter).AssemblyQualifiedName, "Problem Data Type Name", okb.Problems.Select(x => x.DataType.Name).Distinct().ToArray() )); #endregion #region Combined Filters filters.Add(new CombinedFilter(typeof(AndFilter).AssemblyQualifiedName, "AND", BooleanOperation.And)); filters.Add(new CombinedFilter(typeof(OrFilter).AssemblyQualifiedName, "OR", BooleanOperation.Or)); #endregion } return filters.OrderBy(x => x.Label); } public long GetNumberOfRuns(Filter filter) { using (OKBDataContext okb = new OKBDataContext()) { return FilterRuns(okb.Runs, filter, okb).LongCount(); } } public IEnumerable GetRunIds(Filter filter) { using (OKBDataContext okb = new OKBDataContext()) { return FilterRuns(okb.Runs, filter, okb).Select(x => x.Id).ToArray(); } } public IEnumerable GetRuns(IEnumerable ids, bool includeBinaryValues) { using (OKBDataContext okb = new OKBDataContext()) { DataLoadOptions dlo = new DataLoadOptions(); // TODO: specify LoadWiths okb.LoadOptions = dlo; return FilterUnauthorizedRuns(okb.Runs.Where(x => ids.Contains(x.Id)).ToList(), okb).Select(x => Convert.ToDto(x, includeBinaryValues)).ToArray(); } } public IEnumerable GetRunsWithValues(IEnumerable ids, bool includeBinaryValues, IEnumerable valueNames) { using (OKBDataContext okb = new OKBDataContext()) { DataLoadOptions dlo = new DataLoadOptions(); // TODO: specify LoadWiths okb.LoadOptions = dlo; return FilterUnauthorizedRuns(okb.Runs.Where(x => ids.Contains(x.Id)).ToList(), okb).Select(x => Convert.ToDto(x, includeBinaryValues, valueNames)).ToArray(); } } public IEnumerable GetValueNames() { using (OKBDataContext okb = new OKBDataContext()) { return okb.ValueNames.Select(x => Convert.ToDto(x)).ToArray(); } } public IEnumerable GetCharacteristics(long problemId) { using (OKBDataContext okb = new OKBDataContext()) { var prob = okb.Problems.SingleOrDefault(x => x.Id == problemId); if (prob == null) return Enumerable.Empty(); return prob.CharacteristicValues.Select(Convert.ToDto).ToArray(); } } private List FilterRuns(IQueryable runs, Filter filter, OKBDataContext okb) { IFilter f = (IFilter)Activator.CreateInstance(Type.GetType(filter.FilterTypeName), filter); var query = runs.Where(f.Expression); List results = new List(); if (roleVerifier.IsInRole(OKBRoles.OKBAdministrator)) { results.AddRange(query); } else { foreach (DataAccess.Run r in query) { if (IsAuthorizedForAlgorithm(r.AlgorithmId, okb) && IsAuthorizedForProblem(r.ProblemId, okb)) { results.Add(r); } } } return results; } private List FilterUnauthorizedRuns(List runs, OKBDataContext okb) { List results = new List(); if (roleVerifier.IsInRole(OKBRoles.OKBAdministrator)) { results.AddRange(runs); } else { foreach (DataAccess.Run r in runs) { if (IsAuthorizedForAlgorithm(r.AlgorithmId, okb) && IsAuthorizedForProblem(r.ProblemId, okb)) { results.Add(r); } } } return results; } private bool IsAuthorizedForAlgorithm(long algorithmId, OKBDataContext okb) { var algUsers = okb.AlgorithmUsers.Where(x => x.AlgorithmId == algorithmId).Select(x => x.UserGroupId).ToList(); if (algUsers.Count == 0 || userManager.VerifyUser(userManager.CurrentUserId, algUsers)) { return true; } return false; } private bool IsAuthorizedForProblem(long problemId, OKBDataContext okb) { var problemUsers = okb.ProblemUsers.Where(x => x.ProblemId == problemId).Select(x => x.UserGroupId).ToList(); if (problemUsers.Count == 0 || userManager.VerifyUser(userManager.CurrentUserId, problemUsers)) { return true; } return false; } } }