#region License Information /* HeuristicLab * Copyright (C) 2002-2016 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.Threading; using HeuristicLab.Common; using HeuristicLab.Core; using System.Collections.Generic; using System.Linq; namespace HeuristicLab.Clients.Hive { [Item("Hive Administrator", "Hive Administrator")] public sealed class HiveAdminClient : IContent { private static HiveAdminClient instance; public static HiveAdminClient Instance { get { if (instance == null) instance = new HiveAdminClient(); return instance; } } #region Properties private IItemList resources; public IItemList Resources { get { return resources; } } private IItemList downtimes; public IItemList Downtimes { get { return downtimes; } } private Guid downtimeForResourceId; public Guid DowntimeForResourceId { get { return downtimeForResourceId; } set { downtimeForResourceId = value; if (downtimes != null) { downtimes.Clear(); } } } private IItemList projects; public IItemList Projects { get { return projects; } } private Dictionary> projectAncestors; public Dictionary> ProjectAncestors { get { return projectAncestors; } } private Dictionary> projectDescendants; public Dictionary> ProjectDescendants { get { return projectDescendants; } } private Dictionary> resourceAncestors; public Dictionary> ResourceAncestors { get { return resourceAncestors; } } private Dictionary> resourceDescendants; public Dictionary> ResourceDescendants { get { return resourceDescendants; } } #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() { var handler = Refreshed; if (handler != null) handler(this, EventArgs.Empty); } #endregion private HiveAdminClient() { } #region Refresh public void Refresh() { OnRefreshing(); try { resources = new ItemList(); projects = new ItemList(); projectAncestors = new Dictionary>(); projectDescendants = new Dictionary>(); resourceAncestors = new Dictionary>(); resourceDescendants = new Dictionary>(); HiveServiceLocator.Instance.CallHiveService(service => { service.GetSlaveGroupsForAdministration().ForEach(g => resources.Add(g)); service.GetSlavesForAdministration().ForEach(s => resources.Add(s)); service.GetProjectsForAdministration().ForEach(p => projects.Add(p)); }); UpdateResourceGenealogy(resources); UpdateProjectGenealogy(projects); } catch { throw; } finally { OnRefreshed(); } } public void UpdateResourceGenealogy(IItemList resources) { resourceAncestors.Clear(); resourceDescendants.Clear(); foreach (var r in resources) { resourceAncestors.Add(r.Id, new HashSet()); resourceDescendants.Add(r.Id, new HashSet()); } foreach (var r in resources) { var parentResourceId = r.ParentResourceId; while (parentResourceId != null) { var parent = resources.SingleOrDefault(x => x.Id == parentResourceId); if (parent != null) { resourceAncestors[r.Id].Add(parent); resourceDescendants[parent.Id].Add(r); parentResourceId = parent.ParentResourceId; } else { parentResourceId = null; } } } } public void UpdateProjectGenealogy(IItemList projects) { projectAncestors.Clear(); projectDescendants.Clear(); foreach (var p in projects) { projectAncestors.Add(p.Id, new HashSet()); projectDescendants.Add(p.Id, new HashSet()); } foreach (var p in projects) { var parentProjectId = p.ParentProjectId; while (parentProjectId != null) { var parent = projects.SingleOrDefault(x => x.Id == parentProjectId); if (parent != null) { projectAncestors[p.Id].Add(parent); projectDescendants[parent.Id].Add(p); parentProjectId = parent.ParentProjectId; } else { parentProjectId = null; } } } } #endregion #region Refresh downtime calendar public void RefreshCalendar() { if (downtimeForResourceId != null && downtimeForResourceId != Guid.Empty) { OnRefreshing(); try { downtimes = new ItemList(); HiveServiceLocator.Instance.CallHiveService(service => { service.GetDowntimesForResource(downtimeForResourceId).ForEach(d => downtimes.Add(d)); }); } catch { throw; } finally { OnRefreshed(); } } } #endregion #region Store public static void Store(IHiveItem item, CancellationToken cancellationToken) { if (item.Id == Guid.Empty) { if (item is SlaveGroup) { item.Id = HiveServiceLocator.Instance.CallHiveService((s) => s.AddSlaveGroup((SlaveGroup)item)); } if (item is Slave) { item.Id = HiveServiceLocator.Instance.CallHiveService((s) => s.AddSlave((Slave)item)); } if (item is Downtime) { item.Id = HiveServiceLocator.Instance.CallHiveService((s) => s.AddDowntime((Downtime)item)); } if (item is Project) { item.Id = HiveServiceLocator.Instance.CallHiveService(s => s.AddProject((Project)item)); } } else { if (item is SlaveGroup) { HiveServiceLocator.Instance.CallHiveService((s) => s.UpdateSlaveGroup((SlaveGroup)item)); } if (item is Slave) { HiveServiceLocator.Instance.CallHiveService((s) => s.UpdateSlave((Slave)item)); } if (item is Downtime) { HiveServiceLocator.Instance.CallHiveService((s) => s.UpdateDowntime((Downtime)item)); } if (item is Project) { HiveServiceLocator.Instance.CallHiveService((s) => s.UpdateProject((Project)item)); } } } #endregion #region Delete public static void Delete(IHiveItem item) { if (item is SlaveGroup) { HiveServiceLocator.Instance.CallHiveService((s) => s.DeleteSlaveGroup(item.Id)); } else if (item is Slave) { HiveServiceLocator.Instance.CallHiveService((s) => s.DeleteSlave(item.Id)); } else if (item is Downtime) { HiveServiceLocator.Instance.CallHiveService((s) => s.DeleteDowntime(item.Id)); } else if (item is Project) { HiveServiceLocator.Instance.CallHiveService((s) => s.DeleteProject(item.Id)); } } #endregion public void ResetDowntime() { downtimeForResourceId = Guid.Empty; if (downtimes != null) { downtimes.Clear(); } } #region Helper public bool CheckAccessToAdminAreaGranted() { if(projects != null) { return projects.Count > 0; } else { bool accessGranted = false; HiveServiceLocator.Instance.CallHiveService(s => { accessGranted = s.CheckAccessToAdminAreaGranted(); }); return accessGranted; } } public bool CheckOwnershipOfResource(Resource res, Guid userId) { if (res == null || userId == Guid.Empty) return false; if (res.OwnerUserId == userId) { return true; } else if(resourceAncestors.ContainsKey(res.Id)) { return resourceAncestors[res.Id].Where(x => x.OwnerUserId == userId).Any(); } return false; } public bool CheckOwnershipOfProject(Project pro, Guid userId) { if (pro == null || userId == Guid.Empty) return false; if (pro.OwnerUserId == userId) { return true; } else if (projectAncestors.ContainsKey(pro.Id)) { return projectAncestors[pro.Id].Where(x => x.OwnerUserId == userId).Any(); } return false; } public bool CheckOwnershipOfParentProject(Project pro, Guid userId) { if (pro == null || userId == Guid.Empty) return false; if(projectAncestors.ContainsKey(pro.Id)) { return projectAncestors[pro.Id].Where(x => x.OwnerUserId == userId).Any(); } return false; } public bool CheckParentChange(Project child, Project parent) { bool changePossible = true; // change is not possible... // ... if the moved project is null // ... or the new parent is not stored yet // ... or there is not parental change if (child == null || (parent != null && parent.Id == Guid.Empty) || (parent != null && parent.Id == child.ParentProjectId)) { changePossible = false; } else if(parent != null && projectDescendants.ContainsKey(child.Id)) { // ... if the new parent is among the moved project's descendants changePossible = !projectDescendants[child.Id].Where(x => x.Id == parent.Id).Any(); } return changePossible; } public bool CheckParentChange(Resource child, Resource parent) { bool changePossible = true; // change is not possisble... // ... if the moved resource is null // ... or the new parent is not stored yet // ... or the new parent is a slave // ... or there is not parental change if (child == null || (parent != null && parent.Id == Guid.Empty) || (parent != null && parent is Slave) || (parent != null && parent.Id == child.ParentResourceId)) { changePossible = false; } else if (parent != null && resourceDescendants.ContainsKey(child.Id)) { // ... or if the new parent is among the moved resource's descendants changePossible = !resourceDescendants[child.Id].Where(x => x.Id == parent.Id).Any(); } return changePossible; } #endregion } }