#region License Information /* HeuristicLab * Copyright (C) 2002-2014 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 HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using System; using System.Drawing; using System.Linq; namespace HeuristicLab.Optimization.Networks { [Item("ClientPort", "A client port of an optimization network node.")] [StorableClass] public class ClientPort : ClientServicePort, IClientPort { public override Image ItemImage { get { if (Valid) return base.ItemImage; else return HeuristicLab.Common.Resources.VSImageLibrary.Error; } } [Storable] protected IServicePort servicePort; public IServicePort ServicePort { get { return servicePort; } set { if (servicePort != value) { DeregisterServicePortEvents(); servicePort = value; RegisterServicePortEvents(); OnServicePortChanged(); OnInterfaceChanged(); } } } [Storable] protected bool valid; public bool Valid { get { return valid; } protected set { if (value != valid) { valid = value; OnItemImageChanged(); } } } [StorableConstructor] protected ClientPort(bool deserializing) : base(deserializing) { } protected ClientPort(ClientPort original, Cloner cloner) : base(original, cloner) { servicePort = cloner.Clone(original.servicePort); valid = original.valid; RegisterServicePortEvents(); } public ClientPort() : base("ClientPort") { } public ClientPort(string name) : base(name) { } public ClientPort(string name, string description) : base(name, description) { } [StorableHook(HookType.AfterDeserialization)] private void AfterDeserialization() { RegisterServicePortEvents(); } public override IDeepCloneable Clone(Cloner cloner) { return new ClientPort(this, cloner); } public bool IsValidServicePort(IServicePort servicePort) { if (servicePort == null) return false; // check input parameters foreach (var input in servicePort.Parameters.Where(p => p.Type == ServiceParameterType.Input)) { IServiceParameter param; Parameters.TryGetValue(input.Name, out param); if ((param == null) && (input.Value == null)) return false; if (param.Type != input.Type) return false; if (!input.DataType.IsAssignableFrom(param.DataType)) return false; } // check output parameters foreach (var output in Parameters.Where(p => p.Type == ServiceParameterType.Output)) { IServiceParameter param; servicePort.Parameters.TryGetValue(output.Name, out param); if (param == null) return false; if (param.Type != output.Type) return false; if (!output.DataType.IsAssignableFrom(param.DataType)) return false; } return true; } public ServiceParameterCollection PrepareParameters() { if (!Valid) throw new InvalidOperationException("Port configurations do not match"); var parameters = new ServiceParameterCollection(); // collect input parameters (take inputs from service and set default values of client) parameters.AddRange( ServicePort.Parameters. Where(p => p.Type == ServiceParameterType.Input). Select(p => (IServiceParameter)p.Clone()). Select(p => { IServiceParameter param; Parameters.TryGetValue(p.Name, out param); if ((param != null) && (param.Value != null)) p.Value = (IItem)param.Value.Clone(); return p; })); // collect output parameters (take outputs from client) parameters.AddRange( Parameters. Where(p => p.Type == ServiceParameterType.Output). Select(p => (IServiceParameter)p.Clone())); return parameters; } public ServiceParameterCollection Call(ServiceParameterCollection parameters) { if (!Valid) throw new InvalidOperationException("Port configurations do not match"); return ServicePort.Call(parameters); } protected override void OnInterfaceChanged() { Valid = (servicePort != null) && IsValidServicePort(servicePort); base.OnInterfaceChanged(); } public event EventHandler ServicePortChanged; protected virtual void OnServicePortChanged() { var handler = ServicePortChanged; if (handler != null) handler(this, EventArgs.Empty); } #region ServicePort Events protected void RegisterServicePortEvents() { if (servicePort != null) { servicePort.InterfaceChanged += ServicePort_InterfaceChanged; } } protected void DeregisterServicePortEvents() { if (servicePort != null) { servicePort.InterfaceChanged -= ServicePort_InterfaceChanged; } } protected void ServicePort_InterfaceChanged(object sender, EventArgs e) { OnInterfaceChanged(); } #endregion } }