/// <summary> /// Scans the specified directories for primitive components. /// </summary> /// <param name="componentsDirectoryPath">Directories to be scanned.</param> /// <param name="cachedFiles">Paths of files already stored in the cache.</param> private void ScanForPrimitiveComponents(IEnumerable <string> componentsDirectoryPath, ISet <string> cachedFiles) { var pathSet = new HashSet <string>(componentsDirectoryPath); foreach (string dir in pathSet) { string[] filePaths = GetAssemblyFiles(dir); if (filePaths == null) { continue; } foreach (string comp in filePaths) { string fullPath = Path.GetFullPath(comp); if (cachedFiles.Contains(fullPath)) { FilesToGetFromCache.Add(fullPath); } else { AssemblyFileDescriptor assembly = ScanAssembly(fullPath); if (assembly != null) { NewFilesLoaded.Add(assembly); FilesToGetFromCache.Add(fullPath); } } } } }
/// <summary> /// Processes the ComponentScanResults by extracting the new files read during scanning and /// by adding the requested MetadataDefinition to the results. /// </summary> /// <param name="results">The results from scanning.</param> public void ProcessComponentScanResults(ComponentScanResults results) { foreach (string filePath in results.RequestedFiles) { try { FileDescriptor file = this.m_componentFiles[filePath]; if (file is AssemblyFileDescriptor) { AssemblyFileDescriptor assembly = (AssemblyFileDescriptor)file; foreach (ComponentMetadataDefinition metadata in assembly.MetadataCollection) { if (!results.Components.Contains(metadata.ID)) { results.Components.Add(metadata); string GuidID; if (assembly.NewGuidToOldGuid.TryGetValue(metadata.ID, out GuidID)) { results.OldGuidToNewGuidMap.Add(GuidID, metadata.ID); } } else { MetadataDefinition oldMetadata = results.Components[metadata.ID]; string msg = String.Format(Messages.SameComponents, oldMetadata.Classname, oldMetadata.Assembly, metadata.Classname, metadata.Assembly); NLog.LogManager.GetCurrentClassLogger().Warn(msg); results.Errors.Add(msg); } } } else if (file is CompositeComponentFileDescriptor) { CompositeComponentFileDescriptor component = (CompositeComponentFileDescriptor)file; if (!results.CompositeComponents.Contains(component.MetadataDefinition.ID)) { results.CompositeComponents.Add(component.MetadataDefinition); } else { MetadataDefinition oldMetadata = results.CompositeComponents[component.MetadataDefinition.ID]; string msg = String.Format(Messages.SameComponents, oldMetadata.Classname, oldMetadata.Assembly, component.MetadataDefinition.Classname, component.MetadataDefinition.Assembly); NLog.LogManager.GetCurrentClassLogger().Warn(msg); results.Errors.Add(msg); } } } catch (KeyNotFoundException) { } } }
/// <summary> /// Scans the given assembly in search for component definitions. /// In case there are some exception the errors are being collected. /// </summary> /// <param name="assemblyPath">The assembly path.</param> /// <returns>the assembly desriptor with collection of correct MetadataDefinition for all components found inside the assembly. </returns> private AssemblyFileDescriptor ScanAssembly(string assemblyPath) { AssemblyFileDescriptor newAssemblFile = null; try { AssemblyFileDescriptor assemblyFile = new AssemblyFileDescriptor(assemblyPath); var assm = Assembly.LoadFrom(assemblyPath); //get all types from the assembly var types = assm.GetExportedTypes(); foreach (var exportedType in types) { try { //check the type for the component attribute CheckType(assemblyPath, exportedType, assemblyFile); } catch (Exception e) { var message = e.InnerException != null ? e.InnerException.Message : e.Message; message = string.Format("Unable to load component '{0}' in assemblyFile {1}: {2}", exportedType.FullName, assemblyPath, message); Errors.Add(message); } } //even though there could be some errors when loading some components, some other components may be correct, //thus ignore the flag of noErrors. Previously even if just one component failed to load from assembly it didn't show any components //from the given assembly newAssemblFile = assemblyFile; } catch (Exception e) { // Catch everything, just log // Basically, if an exception is thrown, then this is not a valid Component. newAssemblFile = null; string message = e.InnerException != null ? e.InnerException.Message : e.Message; message = string.Format("Unable to load assemblyFile {0}: {1}", assemblyPath, message); Errors.Add(message); } return(newAssemblFile); }
public void FileDescriptorTest() { string componentsDir = System.IO.Path.Combine(AppContext.BaseTestDirectory, "TestComponents"); string componentFile = System.IO.Path.Combine(componentsDir, "Importer.dll"); AssemblyFileDescriptor assembly = new AssemblyFileDescriptor(componentFile); Assert.IsTrue(assembly.isUpToDate()); string id = "MockComponent"; string classname = "MockComponents.MockComponent"; //class exists and should be loaded ComponentMetadataDefinition compMetaDef = new ComponentMetadataDefinition(id, assembly.AbsolutePath, classname); Assert.AreEqual("MockComponents.MockComponent", compMetaDef.Classname); assembly.MetadataCollection.Add(compMetaDef); IList<FileDescriptor> files = new List<FileDescriptor>(); files.Add(assembly); ComponentsLibraryCache cache = new ComponentsLibraryCache(AppContext.BaseTestDirectory); cache.AddComponentFiles(files); Assert.IsTrue(cache.ComponentFiles.Contains(assembly.AbsolutePath)); ISet<string> filepaths = cache.GetUpToDateFiles(); Assert.AreEqual(filepaths.Count, 1); }
public void FileDescriptorNullTest() { FileDescriptor assembly = new AssemblyFileDescriptor(null); }
/// <summary> /// Checks the type for existence of Component Attribute. If type has Component Attribute it creates /// component metadata definition and adds it to the assembly file descriptor. /// If Component Attribute was found, but was in incorrect format error is reported. /// </summary> /// <param name="assemblyPath">The assembly path.</param> /// <param name="exportedType">Type of the exported.</param> /// <param name="assemblyFile">The assembly file.</param> private void CheckType(string assemblyPath, Type exportedType, AssemblyFileDescriptor assemblyFile) { var attribs = exportedType.GetCustomAttributes(typeof(ComponentAttribute), false); if (attribs.Length == 1) { try { var attrib = (ComponentAttribute)attribs[0]; var ioSpecDefinition = ComponentScannerHelper.ReadIOSpec(exportedType); var configurationWrapperDefinition = ComponentScannerHelper.CreateConfigWrapperDefinition(attrib.ConfigurationType); var componentId = ComponentScannerHelper.CreateComponentId(attrib.Name, ioSpecDefinition, attrib.Version, configurationWrapperDefinition); ComponentTags tags = new ComponentTags(componentId); var tagAttribs = exportedType.GetCustomAttributes(typeof(TagAttribute), false); foreach (TagAttribute tag in tagAttribs) { tags.SetTag(tag.Tag, false); } //name participates in guid generation, and is assign as default label, unless other default label has been specified string defaultLabel = (String.IsNullOrWhiteSpace(attrib.DefaultLabel)) ? attrib.Name : attrib.DefaultLabel; //gather all documentation links List <DocumentationLink> documentationLinks = new List <DocumentationLink>(); var linkAttribs = exportedType.GetCustomAttributes(typeof(LinkAttribute), false); foreach (LinkAttribute link in linkAttribs) { Uri url; if (Uri.TryCreate(link.Url, UriKind.Absolute, out url)) { documentationLinks.Add(new DocumentationLink(url, link.Title, link.Description, link.Order)); } else { NLog.LogManager.GetCurrentClassLogger().Warn( String.Format("Documentation link url '{0}' for component '{1}' could not be processed correctly and has been ommitted", link.Url, defaultLabel)); } } var compDef = new ComponentMetadataDefinition(componentId, assemblyPath, exportedType.FullName, ioSpecDefinition, defaultLabel, attrib.Version, attrib.Description, attrib.Author, attrib.IsJava ? Language.JAVA : Language.NET, configurationWrapperDefinition, tags, documentationLinks); assemblyFile.MetadataCollection.Add(compDef); //if old manual guid has been set, add it to the map from new autogenerated guid to old guid if (attrib.GuidIDString != null && attrib.GuidID != null) { string oldGuidID = attrib.GuidID.ToString(); if (!assemblyFile.NewGuidToOldGuid.ContainsValue(oldGuidID)) { assemblyFile.NewGuidToOldGuid.Add(componentId, oldGuidID); } } } catch (Exceptions.ComponentsLibraryException ex) { Errors.Add(String.Format("Potential component type {0} located in assembly {1} has invalid ComponentAttribute: {2}", exportedType, assemblyPath, ex.Message)); } } else if (1 < attribs.Length) { var errorMsg = "ERROR: Somehow there are more than one ComponentAttribute instances on type " + exportedType.FullName; Errors.Add(errorMsg); } }
/// <summary> /// Checks the type for existence of Component Attribute. If type has Component Attribute it creates /// component metadata definition and adds it to the assembly file descriptor. /// If Component Attribute was found, but was in incorrect format error is reported. /// </summary> /// <param name="assemblyPath">The assembly path.</param> /// <param name="exportedType">Type of the exported.</param> /// <param name="assemblyFile">The assembly file.</param> private void CheckType(string assemblyPath, Type exportedType, AssemblyFileDescriptor assemblyFile) { var attribs = exportedType.GetCustomAttributes(typeof(ComponentAttribute), false); if (attribs.Length == 1) { try { var attrib = (ComponentAttribute)attribs[0]; var ioSpecDefinition = ComponentScannerHelper.ReadIOSpec(exportedType); var configurationWrapperDefinition = ComponentScannerHelper.CreateConfigWrapperDefinition(attrib.ConfigurationType); var componentId = ComponentScannerHelper.CreateComponentId(attrib.Name, ioSpecDefinition, attrib.Version, configurationWrapperDefinition); ComponentTags tags = new ComponentTags(componentId); var tagAttribs = exportedType.GetCustomAttributes(typeof(TagAttribute), false); foreach (TagAttribute tag in tagAttribs) { tags.SetTag(tag.Tag, false); } //name participates in guid generation, and is assign as default label, unless other default label has been specified string defaultLabel = (String.IsNullOrWhiteSpace(attrib.DefaultLabel)) ? attrib.Name : attrib.DefaultLabel; //gather all documentation links List<DocumentationLink> documentationLinks = new List<DocumentationLink>(); var linkAttribs = exportedType.GetCustomAttributes(typeof(LinkAttribute), false); foreach (LinkAttribute link in linkAttribs) { Uri url; if (Uri.TryCreate(link.Url, UriKind.Absolute, out url)) { documentationLinks.Add(new DocumentationLink(url, link.Title, link.Description, link.Order)); } else { NLog.LogManager.GetCurrentClassLogger().Warn( String.Format("Documentation link url '{0}' for component '{1}' could not be processed correctly and has been ommitted", link.Url , defaultLabel)); } } var compDef = new ComponentMetadataDefinition(componentId, assemblyPath, exportedType.FullName, ioSpecDefinition, defaultLabel, attrib.Version, attrib.Description, attrib.Author, attrib.IsJava ? Language.JAVA : Language.NET, configurationWrapperDefinition, tags, documentationLinks); assemblyFile.MetadataCollection.Add(compDef); //if old manual guid has been set, add it to the map from new autogenerated guid to old guid if (attrib.GuidIDString != null && attrib.GuidID != null) { string oldGuidID = attrib.GuidID.ToString(); if (!assemblyFile.NewGuidToOldGuid.ContainsValue(oldGuidID)) { assemblyFile.NewGuidToOldGuid.Add(componentId, oldGuidID); } } } catch (Exceptions.ComponentsLibraryException ex) { Errors.Add(String.Format("Potential component type {0} located in assembly {1} has invalid ComponentAttribute: {2}", exportedType, assemblyPath, ex.Message)); } } else if (1 < attribs.Length) { var errorMsg = "ERROR: Somehow there are more than one ComponentAttribute instances on type " + exportedType.FullName; Errors.Add(errorMsg); } }
/// <summary> /// Scans the given assembly in search for component definitions. /// In case there are some exception the errors are being collected. /// </summary> /// <param name="assemblyPath">The assembly path.</param> /// <returns>the assembly desriptor with collection of correct MetadataDefinition for all components found inside the assembly. </returns> private AssemblyFileDescriptor ScanAssembly(string assemblyPath) { AssemblyFileDescriptor newAssemblFile = null; try { AssemblyFileDescriptor assemblyFile = new AssemblyFileDescriptor(assemblyPath); var assm = Assembly.LoadFrom(assemblyPath); //get all types from the assembly var types = assm.GetExportedTypes(); foreach (var exportedType in types) { try { //check the type for the component attribute CheckType(assemblyPath, exportedType, assemblyFile); } catch (Exception e) { var message = e.InnerException != null ? e.InnerException.Message : e.Message; message = string.Format("Unable to load component '{0}' in assemblyFile {1}: {2}", exportedType.FullName, assemblyPath, message); Errors.Add(message); } } //even though there could be some errors when loading some components, some other components may be correct, //thus ignore the flag of noErrors. Previously even if just one component failed to load from assembly it didn't show any components //from the given assembly newAssemblFile = assemblyFile; } catch (Exception e) { // Catch everything, just log // Basically, if an exception is thrown, then this is not a valid Component. newAssemblFile = null; string message = e.InnerException != null ? e.InnerException.Message : e.Message; message = string.Format("Unable to load assemblyFile {0}: {1}", assemblyPath, message); Errors.Add(message); } return newAssemblFile; }