Example #1
0
        private Type[] GetTypesFromAssembly(string assemblyPath, VisualizationLogWriter logWriter)
        {
            try
            {
                // Load the assembly
                Assembly assembly = Assembly.LoadFrom(assemblyPath.Trim());

                // Get the list of types in the assembly.  (This action will fail if there's missing dependent assemblies)
                return(assembly.GetTypes());
            }
            catch (ReflectionTypeLoadException ex)
            {
                // Error most likely caused by trying to load a type that references a missing dependent assembly.
                logWriter.WriteError("Could not load assembly {0}: {1}", assemblyPath, ex.Message);

                // Look into the loader exceptions so we can write out the list of missing dependent assemblies.
                if (ex.LoaderExceptions != null)
                {
                    foreach (Exception loaderException in ex.LoaderExceptions)
                    {
                        logWriter.WriteError(loaderException.Message);
                    }
                }

                return(new Type[] { });
            }
            catch (Exception ex)
            {
                // General error loading assembly
                logWriter.WriteError("Could not load assembly {0}: {1}", assemblyPath, ex.Message);
                return(new Type[] { });
            }
        }
Example #2
0
        private void AddStreamAdapter(Type adapterType, VisualizationLogWriter logWriter, string assemblyPath)
        {
            logWriter.WriteLine("Loading StreamAdapter {0} from {1}...", adapterType.Name, assemblyPath);
            StreamAdapterMetadata streamAdapterMetadata = StreamAdapterMetadata.Create(adapterType, logWriter);

            if (streamAdapterMetadata != null)
            {
                this.streamAdapters.Add(streamAdapterMetadata);
            }
        }
Example #3
0
        private void AddSummarizer(Type summarizerType, VisualizationLogWriter logWriter, string assemblyPath)
        {
            logWriter.WriteLine("Loading Summarizer {0} from {1}...", summarizerType.Name, assemblyPath);
            SummarizerMetadata summarizerMetadata = SummarizerMetadata.Create(summarizerType, logWriter);

            if (summarizerMetadata != null)
            {
                this.summarizers[summarizerType] = summarizerMetadata;
            }
        }
Example #4
0
        private void AddVisualizer(Type visualizationObjectType, VisualizationLogWriter logWriter, string assemblyPath)
        {
            // Add both a "Visualize" and a "Visualize in new panel" command metadata
            logWriter.WriteLine("Loading Visualizer {0} from {1}...", visualizationObjectType.Name, assemblyPath);
            List <VisualizerMetadata> visualizerMetadata = VisualizerMetadata.Create(visualizationObjectType, this.summarizers, this.streamAdapters, logWriter);

            if (visualizerMetadata != null)
            {
                this.visualizers.AddRange(visualizerMetadata);
            }
        }
Example #5
0
        private static Type GetVisualizationObjectDataType(Type visualizationObjectType, VisualizationLogWriter logWriter)
        {
            // Look into the visualization object's base types until we find VisualizationObject<TData>
            // (whose base type is in turn VisualizationObject).
            Type type = visualizationObjectType;

            while ((type != null) && (type.BaseType != typeof(VisualizationObject)))
            {
                type = type.BaseType;
            }

            // Make sure we ultimately derive from VisualizationObject<TData>
            if (type == null)
            {
                logWriter.WriteError("Could not load visualization object {0} because it does not ultimately derive from VisualizationObject", visualizationObjectType.Name);
                return(null);
            }
            else
            {
                // The one and only type argument is the data type of the visualization object
                return(type.GenericTypeArguments[0]);
            }
        }
Example #6
0
        private static VisualizationPanelTypeAttribute GetVisualizationPanelTypeAttribute(Type visualizationObjectType, VisualizationLogWriter logWriter)
        {
            VisualizationPanelTypeAttribute visualizationPanelTypeAttribute = visualizationObjectType.GetCustomAttribute <VisualizationPanelTypeAttribute>();

            if (visualizationPanelTypeAttribute == null)
            {
                logWriter.WriteError("Visualization object {0} could not be loaded because it is not decorated with a VisualizationPanelTypeAttribute", visualizationObjectType.Name);
                return(null);
            }

            return(visualizationPanelTypeAttribute);
        }
Example #7
0
        private static VisualizationObjectAttribute GetVisualizationObjectAttribute(Type visualizationObjectType, VisualizationLogWriter logWriter)
        {
            VisualizationObjectAttribute visualizationObjectAttribute = visualizationObjectType.GetCustomAttribute <VisualizationObjectAttribute>();

            if (visualizationObjectAttribute == null)
            {
                logWriter.WriteError("Visualization object {0} could not be loaded because it is not decorated with a VisualizationObjectAttribute", visualizationObjectType.Name);
                return(null);
            }

            if (string.IsNullOrWhiteSpace(visualizationObjectAttribute.CommandText))
            {
                logWriter.WriteError("Visualization object {0} could not be loaded because its VisualizationObjectAttribute does not specify a Text property", visualizationObjectType.Name);
                return(null);
            }

            if (string.IsNullOrWhiteSpace(visualizationObjectAttribute.IconSourcePath) && string.IsNullOrWhiteSpace(visualizationObjectAttribute.NewPanelIconSourcePath))
            {
                logWriter.WriteError("Visualization object {0} could not be loaded because its VisualizationObjectAttribute does not specify either an IconSourcePath property or a NewPanelIconSourcePath property", visualizationObjectType.Name);
                return(null);
            }

            if (!visualizationObjectAttribute.VisualizationFormatString.Contains(VisualizationObjectAttribute.DefaultVisualizationFormatString))
            {
                logWriter.WriteError("Visualization object {0} could not be loaded because its VisualizationObjectAttribute has an invalid value for the VisualizationFormatString property", visualizationObjectType.Name);
                return(null);
            }

            return(visualizationObjectAttribute);
        }
Example #8
0
        /// <summary>
        /// Creates one or two visualizer metadatas depending on whether a "Visualize in new panel" icon source path was suplied by the visualization object.
        /// </summary>
        /// <param name="visualizationObjectType">The visualization object type.</param>
        /// <param name="summarizers">The list of known summarizers.</param>
        /// <param name="dataAdapters">The list of known data adapters.</param>
        /// <param name="logWriter">The log writer where errors should be written to.</param>
        /// <returns>A list of visualizer metadatas.</returns>
        public static List <VisualizerMetadata> Create(Type visualizationObjectType, Dictionary <Type, SummarizerMetadata> summarizers, List <StreamAdapterMetadata> dataAdapters, VisualizationLogWriter logWriter)
        {
            // Get the visualization object attribute
            VisualizationObjectAttribute visualizationObjectAttribute = GetVisualizationObjectAttribute(visualizationObjectType, logWriter);

            if (visualizationObjectAttribute == null)
            {
                return(null);
            }

            // Get the visualization panel type attribute
            VisualizationPanelTypeAttribute visualizationPanelTypeAttribute = GetVisualizationPanelTypeAttribute(visualizationObjectType, logWriter);

            if (visualizationPanelTypeAttribute == null)
            {
                return(null);
            }

            // Get the message data type for the visualization object.  We will get nothing back
            // if visualizationObjectType does not ultimately derive from VisualizationObject<TData>
            Type visualizationObjectDataType = GetVisualizationObjectDataType(visualizationObjectType, logWriter);

            if (visualizationObjectDataType == null)
            {
                return(null);
            }

            // Get the summarizer type (if the visualizer uses a summarizer)
            SummarizerMetadata summarizerMetadata = null;

            if (visualizationObjectAttribute.SummarizerType != null)
            {
                if (summarizers.ContainsKey(visualizationObjectAttribute.SummarizerType))
                {
                    summarizerMetadata = summarizers[visualizationObjectAttribute.SummarizerType];
                }
                else
                {
                    logWriter.WriteError("Unable to load visualizer {0} because it relies on summarizer {1} which could not be found.", visualizationObjectType.Name, visualizationObjectAttribute.SummarizerType.Name);
                    return(null);
                }
            }

            // If we have a summarizer, make sure its output type matches the input type of the visualization object
            if ((summarizerMetadata != null) && (summarizerMetadata.OutputType != visualizationObjectDataType))
            {
                logWriter.WriteError(
                    "Unable to load visualizer {0} with summarizer {1} because the output type of the summarizer ({2}) does not match the input type of the visualizer ({3}) .",
                    visualizationObjectType.Name,
                    summarizerMetadata.SummarizerType.Name,
                    summarizerMetadata.OutputType.Name,
                    visualizationObjectDataType.Name);

                return(null);
            }

            // Work out the input (message) data type:
            //
            // 1) If there's a summarizer, use the summarizer's input type
            // 2) Otherwise, use the visualization object's data type
            Type dataType = summarizerMetadata != null ? summarizerMetadata.InputType : visualizationObjectDataType;

            List <VisualizerMetadata> metadatas = new List <VisualizerMetadata>();

            // Add the visualization metadata using no adapter
            Create(metadatas, dataType, visualizationObjectType, visualizationObjectAttribute, visualizationPanelTypeAttribute, null);

            // Find all the adapters that have an output type that's the same as the visualization object's data type (or summarizer input type)
            List <StreamAdapterMetadata> usableAdapters = dataAdapters.FindAll(a => dataType == a.OutputType || dataType.IsSubclassOf(a.OutputType));

            // Add the visualization metadata using each of the compatible adapters
            foreach (StreamAdapterMetadata adapterMetadata in usableAdapters)
            {
                Create(metadatas, adapterMetadata.InputType, visualizationObjectType, visualizationObjectAttribute, visualizationPanelTypeAttribute, adapterMetadata);
            }

            return(metadatas);
        }
Example #9
0
        private void DiscoverVisualizerObjects(List <string> assemblies, string visualizerLoadLogFilename)
        {
            bool hasErrors = false;

            // Create the log writer
            using (FileStream fileStream = File.Create(visualizerLoadLogFilename))
            {
                using (VisualizationLogWriter logWriter = new VisualizationLogWriter(fileStream))
                {
                    // Log preamble
                    logWriter.WriteLine("Loading PsiStudio Visualizers ({0})", DateTime.Now.ToString("G"));
                    logWriter.WriteLine("----------------------------------------------------");
                    logWriter.WriteLine();

                    foreach (string assembly in assemblies)
                    {
                        logWriter.WriteLine("Search Assembly: {0}...", assembly);
                    }

                    logWriter.WriteLine();

                    // Note: Visualization object types depend on both summarizer types and stream adapter types,
                    // so we need to make sure those types have all been loaded before we try to load the
                    // visualization object types.
                    Dictionary <Type, string> visualizationObjectTypes = new Dictionary <Type, string>();

                    foreach (string assemblyPath in assemblies)
                    {
                        // Get the list of types in the assembly
                        Type[] types = this.GetTypesFromAssembly(assemblyPath, logWriter);

                        // Look for attributes denoting visualziation objects, summarizers, and stream adapters.
                        foreach (Type type in types)
                        {
                            if (type.GetCustomAttribute <VisualizationObjectAttribute>() != null)
                            {
                                // Don't load these yet, wait until we've loaded the summarizers and adapters.
                                visualizationObjectTypes[type] = assemblyPath;
                            }

                            if (type.GetCustomAttribute <SummarizerAttribute>() != null)
                            {
                                this.AddSummarizer(type, logWriter, assemblyPath);
                            }

                            if (type.GetCustomAttribute <StreamAdapterAttribute>() != null)
                            {
                                this.AddStreamAdapter(type, logWriter, assemblyPath);
                            }
                        }
                    }

                    // Load all of the visualization object types that were found earlier
                    Dictionary <Type, string> .Enumerator visualizationObjectTypesEnumerator = visualizationObjectTypes.GetEnumerator();
                    while (visualizationObjectTypesEnumerator.MoveNext())
                    {
                        this.AddVisualizer(visualizationObjectTypesEnumerator.Current.Key, logWriter, visualizationObjectTypesEnumerator.Current.Value);
                    }

                    // Log complete
                    logWriter.WriteLine();
                    logWriter.WriteLine("PsiStudio visualizer loading has completed. ({0})", DateTime.Now.ToString("G"));

                    hasErrors = logWriter.HasErrors;
                }
            }

            // If there were any errors while loading the visualizers etc, inform the user and allow him to view the log.
            if (hasErrors)
            {
                MessageBoxWindow dlg = new MessageBoxWindow(
                    Application.Current.MainWindow,
                    "Visualizers Load Errors",
                    "One or more visualizers were not loaded because they contained errors.\r\n\r\nWould you like to see the visualizer load log?",
                    "Yes",
                    "No");

                if (dlg.ShowDialog() == true)
                {
                    // Display the log file in the default application for text files.
                    Process.Start(visualizerLoadLogFilename);
                }
            }
        }