/*********************************************************************/ /* */ /* AgentService Framework */ /* www.agentservice.it */ /* */ /* Copyright (C) 2007 l.i.d.o. - DIST, University of Genoa, Italy */ /* GNU Lesser General Public License */ /* */ /* This library is free software; you can redistribute it and/or */ /* modify it under the terms of the GNU Lesser General Public */ /* License as published by the Free Software Foundation, */ /* version 2.1 of the License. */ /* */ /* This library 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 */ /* Lesser General Public License for more details. */ /* */ /* You should have received a copy of the GNU Lesser General Public */ /* License along with this library; if not, write to the */ /* Free Software Foundation, Inc., 59 Temple Place - Suite 330, */ /* Boston, MA 02111-1307, USA. */ /* */ /*********************************************************************/ using System; using System.IO; using System.Reflection; using System.Collections; using System.Collections.Generic; using System.Runtime.Serialization; using AgentService.Agent; using AgentService.Platform; using AgentService.Platform.Modules; using AgentService.Interop; using AgentServiceDefaultModule; namespace AgentService.Platform.Modules.Default { /// /// Class StorageConfiguration. Mantains /// the configuration of the storage module. /// public class StorageSettings { /// /// mappings between the types which /// are of interest for AgentService /// and the corresponding assemblies. /// protected Mappings mappings; /// /// Gets, sets the mappings between /// the types of the assemblies. /// public Mappings Mappings { get { return this.mappings; } set { this.mappings = value; } } /// /// storage synchronization flag /// protected bool bNeedSync; /// /// Gets, sets the synchronization flag. /// If true the storage needs to be /// synchronized. /// public bool NeedSync { get { return this.bNeedSync; } set { this.bNeedSync = value; } } /// /// reflection only flag /// protected bool bReflectionOnly; /// /// Gets, sets the flag that selects /// the use of the ReflectionOnly API /// for inspecting the libraries which /// are mantained by the storage module. /// public bool ReflectionOnly { get { return this.bReflectionOnly; } set { this.bReflectionOnly = value; } } /// /// signed only flag /// protected bool bSignedOnly; /// /// Gets, sets the flag controlling /// the use of unsigned assemblies. If /// true only signed assemblies are /// allowed. /// public bool SignedOnly { get { return this.bSignedOnly; } set { this.bSignedOnly = value; } } /// /// Directory hosting the repository /// protected string baseDirectory; /// /// Gets, sets the base directory /// hosting the repository. /// public string BaseDirectory { get { return this.baseDirectory; } set { this.baseDirectory = value; } } /// /// Creates a StorageSettings instance. All the /// boolean properties are set to false and the /// Mappings instance is empty. /// public StorageSettings() { this.mappings = new Mappings(); this.bNeedSync = false; this.bReflectionOnly = false; this.bSignedOnly = false; this.baseDirectory = string.Empty; } /// /// Creates a StorageSettings instance with the given parameters. /// /// mappings between the types and their corresponding assemblies /// synchronization flag /// signed assemblies only flag /// reflection only API flag /// base directory hosting the repository public StorageSettings(Mappings mappings, bool bNeedSync, bool bSignedOnly, bool bReflectionOnly, string baseDirectory) { this.mappings = mappings; this.bNeedSync = bNeedSync; this.bSignedOnly = bSignedOnly; this.bReflectionOnly = bReflectionOnly; this.baseDirectory = baseDirectory; } } /// /// Class Mappings. Holds the references to the array /// of TypeDescriptor objects used to mantain the /// information about the mapping. /// [Serializable] public class Mappings { /// /// Type information about the agent /// templates stored in the storage. /// public AgentTemplateDescriptor[] Templates; /// /// Type information about the knowledge /// types stored in the sotrage. /// public KnowledgeDescriptor[] Knowledges; /// /// Type information about the behaviour /// types stored in the storage. /// public BehaviourDescriptor[] Behaviours; /// /// List of managed assemblie hold in /// the storage. /// public AssemblyName[] Assemblies; /// /// Hashtable containing the mappings /// between the name of the type and /// its descriptor. /// public Hashtable TypeMap; /// /// Deserialization constructor; /// /// serialization bag /// serialization context public Mappings(SerializationInfo info, StreamingContext context) { this.Templates = info.GetValue("templates", typeof(AgentTemplateDescriptor[])) as AgentTemplateDescriptor[]; this.Assemblies = info.GetValue("assemblies", typeof(AssemblyName[])) as AssemblyName[]; this.Behaviours = info.GetValue("behaviours", typeof(BehaviourDescriptor[])) as BehaviourDescriptor[]; this.Knowledges = info.GetValue("knowledges", typeof(KnowledgeDescriptor[])) as KnowledgeDescriptor[]; this.TypeMap = info.GetValue("typeMap", typeof(Hashtable)) as Hashtable; } /// /// Constructs a Mappings instance. /// public Mappings() { this.Templates = new AgentTemplateDescriptor[0]; this.Knowledges = new KnowledgeDescriptor[0]; this.Behaviours = new BehaviourDescriptor[0]; this.Assemblies = new AssemblyName[0]; this.TypeMap = new Hashtable(); } /// /// Custom serialization method. /// /// serialization bag /// serialization context public void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("templates", this.Templates); info.AddValue("assemblies", this.Assemblies); info.AddValue("behaviours", this.Behaviours); info.AddValue("knowledges", this.Knowledges); info.AddValue("typeMap", this.TypeMap); } /// /// Deserialize the Mappings instance from the given string. /// /// string version of the Mappings instance /// deserialized Mappings instance public static Mappings Deserialize(string strMappings) { string[] bytes = strMappings.Split('.'); byte[] buffer = new byte[bytes.Length]; for (int ndx = 0; ndx < bytes.Length; ndx++) { buffer[ndx] = Byte.Parse(bytes[ndx]); } System.IO.MemoryStream ms = new System.IO.MemoryStream(buffer); System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); bf.Binder = new AgentServiceDefaultModule.ASBinder(); return (Mappings)bf.Deserialize(ms); } /// /// Serialize the hastable into a string /// /// serialized version of the mapping object into a string public string Serialize() { System.IO.MemoryStream ms = new System.IO.MemoryStream(); System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); bf.Binder = new ASBinder(); bf.Serialize(ms, this); System.Text.StringBuilder sb = new System.Text.StringBuilder(); byte[] bytes = ms.GetBuffer(); for (int ndx = 0; ndx < bytes.Length; ndx++) { sb.Append(bytes[ndx]); if (ndx < bytes.Length - 1) { sb.Append("."); } } return sb.ToString(); } } /// /// Class StorageInfo. Holds installation information for the storage module. /// [Serializable] public class StorageInfo : InstallationInfo { /// /// base directory for the storage /// public string baseDir; /// /// Constructs a StorageInfo object. /// /// base directory for the storage public StorageInfo(string baseDirectory) { this.baseDir = baseDirectory; } } /// /// Class DefaultStorageModule. Default implementation of the IStorageModule interface. /// public class DefaultStorageModule : AgentService.Platform.Modules.IStorageModule { /// /// Platform accessible data /// private AgentService.Platform.IPlatformContext hapContext; /// /// Configuration file /// private string configFile; /// /// Information about the module /// private ModuleInfo info; /// /// Token owned by the module to deregister an event sink previously registered /// private int sinkToken; /// /// Last error occurred in the module /// private IModuleError lastError; /// /// synchronization handle(used for /// concurrent accesses to the services /// of the storage). /// private object syncRoot = new object(); /// /// Synchronizer object. /// private Synchronizer synchronizer = null; /// /// storage settings. /// private StorageSettings settings = null; /// /// Constructs a default storage module /// public DefaultStorageModule() { this.settings = new StorageSettings(); } #region IPlatformModule Members /// /// name of the module /// private string name = "Default Storage Module"; /// /// Gets the name of the module /// public string Name { get { return this.name; } } /// /// description of the module /// private string description = "Provides a default implementation of the starage subsystem that relies on a specified portion of the file system"; /// /// Gets a summary description of the module /// public string Description { get { return this.description; } } /// /// Gets the module category /// public AgentService.Platform.Modules.ModuleCategory Category { get { return AgentService.Platform.Modules.ModuleCategory.Storage; } } /// /// Gets a bool value indicating if the module is /// able to perform the main functionality of the /// belonging category. If the bool value is false /// the maodule is not a main module. This means that /// in the case of the Messaging Category the module /// can be a filter. If the bool value is true insted /// the module can perform all the base functionalities /// required by the messaging subsystem /// public bool IsMain { get { return true; } } /// /// Checks wheter the module supports features defined in a given interface. /// If the these features are supported the module reference can be subject to /// cast against the requested interface. /// /// full name of the interface that /// true if the specified interface is supported public bool CanSupport(string capabiltyInterface) { return false; } /// /// Returns the last error occurred in the module, null if there /// are no errors to return /// /// Reference to the error. public IModuleError GetLastError() { return this.lastError; } /// /// Attaches the module to the platform. Called by the platform /// when the module is loaded. /// /// reference to the instance of the hosting platform /// information about the module /// returns true is the operation has been successfulland with no errors public bool Attach(IPlatformContext hostingPlatform, ModuleInfo info) { // retrieves base directory from the configuration file this.hapContext = hostingPlatform; this.info = info; try { this.configFile = System.IO.Path.Combine(this.hapContext.PlatformBaseDir, this.hapContext.PlatformCoreConfPath); this.configFile = System.IO.Path.Combine(this.configFile, this.info.ConfigFile); this.ReadData(); if (this.settings.ReflectionOnly == true) { this.synchronizer = new ReflectionOnlySynchronizer(this.hapContext.PlatformBaseDir, this.hapContext.PlatformCoreBinPath, this.settings.BaseDirectory, this.settings.SignedOnly); } else { this.synchronizer = new AppDomainSynchronizer(this.hapContext.PlatformBaseDir, this.hapContext.PlatformCoreBinPath, this.settings.BaseDirectory, this.settings.SignedOnly); } } catch(System.Exception ex) { this.lastError = new ModuleError((int)ModuleErrorCodes.InternalError, this.info, "Could not read configuration file", ex); return false; } // registers the event sink for the module AgentService.Platform.PlatformEventSinkHandler handler = new PlatformEventSinkHandler(this.DispatchSinkEvent); AgentService.Platform.SinkStatusCodes code = this.hapContext.RegisterEventSink(StorageSinkEvent.GetDescriptor(),handler,out this.sinkToken); if (code != AgentService.Platform.SinkStatusCodes.SinkOk) { this.lastError = new ModuleError((int)ModuleErrorCodes.InternalError, this.info, "Error registering storage event sink with code [{0}]" + code.ToString()); } return true; } /// /// Detaches the module from the platform Called by the platform when /// the module is unloaded /// /// true if the operation has been successful public bool Detach() { AgentService.Platform.SinkStatusCodes code = this.hapContext.DeregisterEventSink(StorageSinkEvent.GetDescriptor(),this.sinkToken); if (code != AgentService.Platform.SinkStatusCodes.SinkOk) { this.lastError = new ModuleError((int)ModuleErrorCodes.InternalError, this.info, "Error deregistering storage event sink with code [{0}]" + code.ToString()); } try { lock(this.syncRoot) { this.Synchronize(); this.WriteData(); return true; } } catch(System.IO.IOException ioex) { this.lastError = new ModuleError((int)ModuleErrorCodes.InternalError, this.info, "An I/O error occurred while detaching th module", ioex); return false; } } /// /// Installs a the module in the platform. Called by the pltaform when the module is /// installed. /// /// platform accessible data /// configuration file /// installation info object used to store install information /// true if the installation process has been successful public bool Install(IPlatformContext hostingPlatform, ModuleInfo info, ref InstallationInfo instInfo) { this.hapContext = hostingPlatform; this.info = info; try { this.settings.BaseDirectory = System.IO.Path.Combine(hostingPlatform.PlatformBaseDir, @"storage"); this.configFile = System.IO.Path.Combine(this.hapContext.PlatformBaseDir, this.hapContext.PlatformCoreConfPath); this.configFile = System.IO.Path.Combine(this.configFile, this.info.ConfigFile); this.WriteData(); System.IO.Directory.CreateDirectory(this.settings.BaseDirectory); instInfo = new StorageInfo(this.settings.BaseDirectory); return true; } catch(System.IO.IOException ioex) { this.lastError = new ModuleError((int)ModuleErrorCodes.InternalError, this.info, "Unexpected IO error", ioex); return false; } } /// /// Uninstall the module. Called by the platform when the module is removed permanently /// from the platform /// /// installation info object used to install the module /// true if the uninstall process has been successfull public bool UnInstall(InstallationInfo instInfo) { if (this.settings != null) { this.settings = new StorageSettings(); } StorageInfo stInfo = instInfo as StorageInfo; if (stInfo != null) { this.settings.BaseDirectory = stInfo.baseDir; System.IO.Directory.Delete(this.settings.BaseDirectory); return true; } return false; } #endregion #region IStorageModule Members /// /// Removes an assembly from the storage /// /// assembly file name /// true, if successful public bool RemoveAssembly(string name) { try { System.IO.File.Delete(System.IO.Path.Combine(this.settings.BaseDirectory,name)); this.lastError = null; this.settings.NeedSync = true; return true; } catch(System.IO.IOException ioe) { this.lastError = new ModuleError((int)ModuleErrorCodes.InternalError, this.info, "cannot Remove assembly " + name, ioe); return false; } } /// /// Adds an assembly to the storage /// /// path to the assembly file to add /// if true replace the existing assembly file if exists /// true, if successful public bool AddAssembly(string path, bool bReplaceIfExists) { string assembly = System.IO.Path.GetFileName(path); //demartini path = string.Concat(this.hapContext.PlatformBaseDir, "\\", assembly); //string aaaa = string.Concat(this.hapContext.PlatformBaseDir, "\\", assembly); //path = aaaa; try { string dest = System.IO.Path.Combine(this.settings.BaseDirectory, assembly); if ((System.IO.File.Exists(dest) == true) && (bReplaceIfExists == false)) { this.lastError = new ModuleError((int)ModuleErrorCodes.InternalError, this.info, String.Format("Assembly {0} already exists in the storage", dest)); return false; } System.IO.File.Copy(path,dest,bReplaceIfExists); this.lastError = null; this.settings.NeedSync = true; return true; } catch(System.IO.IOException ioe) { this.lastError = new ModuleError((int)ModuleErrorCodes.InternalError, this.info, String.Format("cannot Add assembly {0} to repository", assembly), ioe); return false; } } /// /// Executes a copy of an assembly mantained in the storage. /// /// assembly file name /// destination path /// true if the copy is successfull public bool CopyAssembly(string fileName, string newPath) { try { string source = Path.Combine(this.settings.BaseDirectory, fileName); FileStream fsSource = new FileStream(source,FileMode.Open, FileAccess.Read); FileStream fsDest = new FileStream(newPath,FileMode.Create, FileAccess.Write); byte[] buffer = new byte[1024]; int offset = 0; int count = 1024; do { count = fsSource.Read(buffer, offset, count); if (count > 0) { fsDest.Write(buffer,offset,count); offset += count; if (offset == buffer.Length) { count = 1024; offset = 0; } else { count = buffer.Length - offset; } } } while(count > 0); fsSource.Close(); fsDest.Close(); return true; } catch(ArgumentNullException ioex) { this.lastError = new ModuleError((int)ModuleErrorCodes.InternalError, this.info, "Invalid parameter", ioex); return false; } catch(ArgumentException ioex) { this.lastError = new ModuleError((int)ModuleErrorCodes.InternalError, this.info, "Invalid parameter", ioex); return false; } } /// /// Clears the storage. /// /// true if successful public bool ClearStorage() { try { lock(this.syncRoot) { System.IO.Directory.Delete(this.settings.BaseDirectory); System.IO.Directory.CreateDirectory(this.settings.BaseDirectory); this.lastError = null; this.settings.Mappings = new Mappings(); return true; } } catch(System.IO.IOException ioe) { this.lastError = new ModuleError((int)ModuleErrorCodes.InternalError, this.info, "cannot Remove all the assemblies in repository", ioe); return false; } } /// /// Gets the information about the type /// corresponding to the given full type /// name. /// /// full type name /// type descriptor object if found, null otherwise public TypeDescriptor GetAssemblyFor(string type) { lock(this.syncRoot) { TypeDescriptor td = null; if (this.Synchronize() == true) { td = this.settings.Mappings.TypeMap[type] as TypeDescriptor; if (td == null) { this.lastError = new ModuleError((int)ModuleErrorCodes.InternalError, this.info, string.Format("AgentTemplate,Knowledge or Behaviour {0} does not exists in the repository.", type)); } } // return System.IO.Path.Combine(this.baseDirectory,assembly); return td; } } /// /// Gets the list of the dependent assemblies for the given /// assembly file name. /// /// assembly file name /// list of dependent assemblies public System.Reflection.AssemblyName[] GetDependentAssemblies(string assemblyName) { try { string assemblyPath = System.IO.Path.Combine(this.settings.BaseDirectory, assemblyName); System.Reflection.Assembly assembly = System.Reflection.Assembly.ReflectionOnlyLoadFrom(assemblyPath); this.lastError = null; return assembly.GetReferencedAssemblies(); } catch(System.IO.IOException ioe) { this.lastError = new ModuleError((int)ModuleErrorCodes.InternalError, this.info, "cannot gets all the referenced assemblies", ioe); return null; } } /// /// Synchronizes the storage phisical content with repository of AgentTemplate types. /// Note: Call after AddAssembly, RemoveAssembly /// public bool Synchronize() { #region OLDCODE /* if (this.bNeedSync) { lock(this.syncRoot) { // retrieve all dll files from the base directory string pattern = "*.dll"; string[] dlls = System.IO.Directory.GetFiles(this.baseDirectory, pattern); ArrayList alTemplates = new ArrayList(); ArrayList alKnowledges = new ArrayList(); ArrayList alBehaviours = new ArrayList(); ArrayList al = new ArrayList(); this.mappings.TypeMap.Clear(); foreach(string dll in dlls) { try { System.Reflection.Assembly assembly = System.Reflection.Assembly.LoadFrom(dll); Type[] types = assembly.GetExportedTypes(); foreach(Type type in types) { byte[] pkt = type.Assembly.GetName().GetPublicKeyToken(); TypeDescriptor td = new TypeDescriptor(type.FullName, type.Assembly.GetName().Name, pkt); if (type.IsSubclassOf(typeof(AgentService.Agent.AgentTemplate)) == true) { alTemplates.Add(td); } if (type.IsSubclassOf(typeof(AgentService.Agent.Behaviour.Behaviour)) == true) { alKnowledges.Add(td); } if (type.IsSubclassOf(typeof(AgentService.Agent.Knowledge.Knowledge)) == true) { alBehaviours.Add(td); } this.mappings.TypeMap[td.FullTypeName] = td; } al.Add(assembly.GetName()); } catch(System.TypeLoadException tex) { } catch(System.BadImageFormatException imgex) { // just skip, it could be a not managed dll } } this.mappings.Templates = (TypeDescriptor[]) alTemplates.ToArray(typeof(TypeDescriptor)); this.mappings.Knowledges = (TypeDescriptor[]) alKnowledges.ToArray(typeof(TypeDescriptor)); this.mappings.Behaviours = (TypeDescriptor[]) alBehaviours.ToArray(typeof(TypeDescriptor)); this.mappings.Assemblies = (AssemblyName[]) al.ToArray(typeof(AssemblyName)); this.bNeedSync = false; } } return true; */ #endregion if (this.settings.NeedSync == true) { lock (this.syncRoot) { this.settings.Mappings.TypeMap.Clear(); Mappings tmp = this.synchronizer.Do(); if (tmp == null) { this.lastError = new ModuleError((int) ModuleErrorCodes.InternalError, this.info, "Could not Synchronize the storage", this.synchronizer.Exception); return false; } else { this.settings.Mappings = tmp; } } } this.settings.NeedSync = false; return true; } /// /// returns all the assemblies that the platform uses /// public System.Reflection.AssemblyName[] GetStoredAssemblies() { lock(this.syncRoot) { if (this.Synchronize() == true) { return this.settings.Mappings.Assemblies; } else { return null; } } } /// /// Gets all the templates stored in the assembly loaded into the platform /// public AgentTemplateDescriptor[] GetStoredAgentTemplates() { lock(this.syncRoot) { if (this.Synchronize() == true) { return this.settings.Mappings.Templates; } else { return null; } } } /// /// Get the templatedescriptor stored in the assembly loaded into the platform. /// /// a descriptor of the type containing the full type name and /// the assembly information public AgentTemplateDescriptor GetStoredAgentTemplateFor(string typename) { lock (this.syncRoot) { if (this.Synchronize() == true) { AgentTemplateDescriptor descriptor = null; foreach (AgentTemplateDescriptor agt in this.settings.Mappings.Templates) { if (agt.FullTypeName.CompareTo(typename) == 0) { descriptor = agt; break; } } return descriptor; } return null; } } /// /// Gets all the templates stored for the given assembly /// /// Name of the assembly public AgentTemplateDescriptor[] GetStoredAgentTemplatesFor(string assemblyname) { lock (this.syncRoot) { if (this.Synchronize() == true) { ArrayList agts = new ArrayList(); foreach (AgentTemplateDescriptor agt in this.settings.Mappings.Templates) { if (agt.AssemblyName.CompareTo(assemblyname) == 0) { agts.Add(agt); } } return ((AgentTemplateDescriptor[])agts.ToArray(typeof(AgentTemplateDescriptor))); } return null; } } /// /// Gets all the Behaviour classes used by agents into the platform /// public BehaviourDescriptor[] GetStoredBehaviours() { lock(this.syncRoot) { if (this.Synchronize() == true) { return this.settings.Mappings.Behaviours; } return null; } } /// /// Gets all the Behaviour classes in the given assembly /// /// Name of the assembly public BehaviourDescriptor[] GetStoredBehavioursFor(string assemblyname) { lock (this.syncRoot) { if (this.Synchronize() == true) { ArrayList bds = new ArrayList(); foreach (BehaviourDescriptor bd in this.settings.Mappings.Behaviours) { if (bd.AssemblyName.CompareTo(assemblyname) == 0) { bds.Add(bd); } } return ((BehaviourDescriptor[])bds.ToArray(typeof(BehaviourDescriptor))); } return null; } } /// /// Gets all the Knowledge classes used by agents into the platform /// public KnowledgeDescriptor[] GetStoredKnowledges() { lock(this.syncRoot) { if (this.Synchronize() == true) { return this.settings.Mappings.Knowledges; } return null; } } /// /// Gets all the Knowledge classes in the given assembly /// /// Name of the assembly public KnowledgeDescriptor[] GetStoredKnowledgesFor(string assemblyname) { lock (this.syncRoot) { if (this.Synchronize() == true) { ArrayList kds = new ArrayList(); foreach (KnowledgeDescriptor kd in this.settings.Mappings.Knowledges) { if (kd.AssemblyName.CompareTo(assemblyname) == 0) { kds.Add(kd); } } return ((KnowledgeDescriptor[])kds.ToArray(typeof(KnowledgeDescriptor))); } return null; } } #endregion #region Worker methods /// /// Writes the module data to the /// configuration file. /// public void WriteData() { System.IO.StreamWriter writer = new System.IO.StreamWriter(this.configFile); writer.WriteLine(this.settings.BaseDirectory); // we do not lock the instance since while // the module is being installed there is // no risk of race conditions on the mappings // instance. writer.WriteLine(this.settings.Mappings.Serialize()); writer.WriteLine(this.settings.NeedSync); writer.WriteLine(this.settings.SignedOnly); writer.WriteLine(this.settings.ReflectionOnly); writer.Close(); } /// /// Reads the module data from /// the configuration file. /// public void ReadData() { System.IO.StreamReader reader = new System.IO.StreamReader(this.configFile); this.settings.BaseDirectory = reader.ReadLine(); string strMappings = reader.ReadLine(); this.settings.NeedSync = bool.Parse(reader.ReadLine()); this.settings.SignedOnly = bool.Parse(reader.ReadLine()); this.settings.ReflectionOnly = bool.Parse(reader.ReadLine()); // we do not need to lock the object // here because while the module is // being attached there is no risk of // race conditions this.settings.Mappings = Mappings.Deserialize(strMappings); reader.Close(); } /// /// Handles all the events issued to the module. /// /// sender of the event /// event arguments private void DispatchSinkEvent(object sender, PlatformSinkEventArgs sinkEvent) { StorageSinkEvent storageEvent = sinkEvent.Event as StorageSinkEvent; if (storageEvent == null) { storageEvent.Result = false; this.lastError = new ModuleError((int)ModuleErrorCodes.InternalError, this.info, "Invalid Sink event"); return; } switch (storageEvent.Action) { case StorageActions.AddAssembly: { this.AddAssembly(storageEvent.Param, false); // CHANGE: 4/2/2006: added the syncronization of // the storage lock (this.syncRoot) { this.Synchronize(); } storageEvent.Result = this.lastError == null; } break; case StorageActions.CopyAssembly: { this.CopyAssembly(storageEvent.Param, storageEvent.Param2); storageEvent.Result = this.lastError == null; } break; case StorageActions.RemoveAssembly: { this.RemoveAssembly(storageEvent.Param); storageEvent.Result = this.lastError == null; } break; case StorageActions.QueryType: { TypeDescriptor foundInGAC = this.IsAssemblyInGAC(storageEvent.Param); if (foundInGAC == null) { TypeDescriptor td = this.GetAssemblyFor(storageEvent.Param); if (td == null) { storageEvent.Types = null; } else { storageEvent.Types = new TypeDescriptor[1] { td }; } } else { storageEvent.Types = new TypeDescriptor[1] { foundInGAC }; } storageEvent.Result = this.lastError == null; } break; case StorageActions.QueryAssemblies: { storageEvent.Assemblies = this.GetStoredAssemblies(); storageEvent.Result = this.lastError == null; } break; case StorageActions.QueryTemplates: { storageEvent.Types = this.GetStoredAgentTemplates(); storageEvent.Result = this.lastError == null; } break; case StorageActions.QueryKnowledges: { storageEvent.Types = this.GetStoredKnowledges(); storageEvent.Result = this.lastError == null; } break; case StorageActions.QueryBehaviours: { storageEvent.Types = this.GetStoredBehaviours(); storageEvent.Result = this.lastError == null; } break; } } /// /// Checks if the type belongs to an assembly loaded from the global /// assembly cache /// /// Type to check /// True if found /// For now this method only check if the type to check belongs /// to the mscorlib assembly private TypeDescriptor IsAssemblyInGAC (string typeToCheck) { try { Type type = System.Reflection.Assembly.GetAssembly(typeof(string)).GetType(typeToCheck,true); return new TypeDescriptor(type); } catch (System.Exception) { return null; } } #endregion } }