/*********************************************************************/
/* */
/* 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
}
}