Esempio n. 1
0
        /// <summary>
        /// Load a model from an input stream
        /// </summary>
        /// <param name="inputStream">The stream to input from.</param>
        /// <returns>A <see cref="Store"/> with the model loaded.</returns>
        public Store Load(Stream inputStream)
        {
            List <string> unrecognizedNamespaces  = null;
            Stream        namespaceStrippedStream = null;
            Store         store = null;

            try
            {
                XmlReaderSettings readerSettings  = new XmlReaderSettings();
                ExtensionLoader   extensionLoader = myExtensionLoader;
                readerSettings.CloseInput = false;
                Dictionary <string, ExtensionModelBinding> documentExtensions = null;
                using (XmlReader reader = XmlReader.Create(inputStream, readerSettings))
                {
                    reader.MoveToContent();
                    if (reader.NodeType == XmlNodeType.Element)
                    {
                        if (reader.MoveToFirstAttribute())
                        {
                            do
                            {
                                if (reader.Prefix == "xmlns")
                                {
                                    string URI = reader.Value;
                                    if (!string.Equals(URI, ORMCoreDomainModel.XmlNamespace, StringComparison.Ordinal) &&
                                        !string.Equals(URI, ORMShapeDomainModel.XmlNamespace, StringComparison.Ordinal) &&
                                        !string.Equals(URI, ORMSerializationEngine.RootXmlNamespace, StringComparison.Ordinal))
                                    {
                                        ExtensionModelBinding?extensionType = extensionLoader.GetExtensionDomainModel(URI);
                                        if (extensionType.HasValue)
                                        {
                                            if (documentExtensions == null)
                                            {
                                                documentExtensions = new Dictionary <string, ExtensionModelBinding>();
                                            }
                                            documentExtensions[URI] = extensionType.Value;
                                        }
                                        else
                                        {
                                            (unrecognizedNamespaces ?? (unrecognizedNamespaces = new List <string>())).Add(URI);
                                        }
                                    }
                                }
                            } while (reader.MoveToNextAttribute());
                        }
                    }
                }
                extensionLoader.VerifyRequiredExtensions(ref documentExtensions);

                if (unrecognizedNamespaces != null)
                {
                    inputStream.Position    = 0;
                    namespaceStrippedStream = ExtensionLoader.CleanupStream(inputStream, extensionLoader.StandardDomainModels, documentExtensions.Values, unrecognizedNamespaces);
                    if (namespaceStrippedStream != null)
                    {
                        inputStream = namespaceStrippedStream;
                    }
                    else
                    {
                        unrecognizedNamespaces = null;
                    }
                }
                inputStream.Position = 0;
                store = CreateStore();
                store.UndoManager.UndoState = UndoState.Disabled;
                store.LoadDomainModels(extensionLoader.GetRequiredDomainModels(documentExtensions));

                try
                {
                    ModelingEventManager eventManager = ModelingEventManager.GetModelingEventManager(store);
                    using (Transaction t = store.TransactionManager.BeginTransaction("File load and fixup"))
                    {
                        foreach (IModelingEventSubscriber subscriber in Utility.EnumerateDomainModels <IModelingEventSubscriber>(store.DomainModels))
                        {
                            subscriber.ManageModelingEventHandlers(eventManager, EventSubscriberReasons.DocumentLoading | EventSubscriberReasons.ModelStateEvents, EventHandlerAction.Add);
                        }
                        if (inputStream.Length > 1)
                        {
                            (new ORMSerializationEngine(store)).Load(inputStream);
                        }
                        t.Commit();
                    }
                    foreach (IModelingEventSubscriber subscriber in Utility.EnumerateDomainModels <IModelingEventSubscriber>(store.DomainModels))
                    {
                        subscriber.ManageModelingEventHandlers(eventManager, EventSubscriberReasons.DocumentLoaded | EventSubscriberReasons.ModelStateEvents, EventHandlerAction.Add);
                    }
                    store.UndoManager.UndoState = UndoState.Enabled;
                }
                catch (TypeInitializationException ex)
                {
                    // If the type that failed to load is an extensions, then remove it from
                    // the list of available extensions and try again.
                    if (documentExtensions != null)
                    {
                        string typeName = ex.TypeName;
                        foreach (KeyValuePair <string, ExtensionModelBinding> pair in documentExtensions)
                        {
                            Type testType = pair.Value.Type;
                            if (testType.FullName == typeName)
                            {
                                if (extensionLoader.CustomExtensionUnavailable(testType))
                                {
                                    return(Load(inputStream));
                                }
                                break;
                            }
                        }
                    }
                    throw;
                }
            }
            finally
            {
                if (namespaceStrippedStream != null)
                {
                    namespaceStrippedStream.Dispose();
                }
            }
            return(store);
        }
Esempio n. 2
0
        public static void ShowDialog(IServiceProvider serviceProvider, ORMDesignerDocData docData)
        {
            ExtensionManager extensionManager = new ExtensionManager(docData.Store);
            IWin32Window     dialogOwner      = Utility.GetDialogOwnerWindow(serviceProvider);

            if (extensionManager.ShowDialog(dialogOwner) == DialogResult.OK)
            {
                // TODO: Prompt the user to make sure they really want us to start deleting stuff...

                ListView.CheckedListViewItemCollection checkedItems = extensionManager.lvExtensions.CheckedItems;
                ExtensionLoader extensionLoader = ORMDesignerPackage.ExtensionLoader;
                IDictionary <string, ExtensionModelBinding> availableExtensions = extensionLoader.AvailableCustomExtensions;
                Dictionary <string, ExtensionModelBinding>  checkedTypes        = new Dictionary <string, ExtensionModelBinding>(availableExtensions.Count);
                foreach (ListViewItem listViewItem in checkedItems)
                {
                    string extensionNamespace = (string)listViewItem.Tag;
                    checkedTypes.Add(extensionNamespace, availableExtensions[extensionNamespace]);
                }

                // Make sure all required extensions are turned on. This will turn previously ignored
                // secondary extensions back on.
                extensionLoader.VerifyRequiredExtensions(ref checkedTypes);

                Stream currentStream  = null;
                Stream newStream      = null;
                Stream modifiedStream = null;
                try
                {
                    Object streamObj;
                    EnvDTE.IExtensibleObject docDataExtender = (EnvDTE.IExtensibleObject)docData;
                    docDataExtender.GetAutomationObject("ORMXmlStream", null, out streamObj);
                    currentStream = streamObj as Stream;

                    Debug.Assert(currentStream != null);

                    // Allow each domain model that is being removed to run custom code immediately before the
                    // unload process.
                    Transaction customUnloadTransaction = null;
                    Store       store = docData.Store;
                    try
                    {
                        IDomainModelUnloading[] unloadingModels = ((IFrameworkServices)store).GetTypedDomainModelProviders <IDomainModelUnloading>();
                        if (unloadingModels != null)
                        {
                            for (int i = 0; i < unloadingModels.Length; ++i)
                            {
                                IDomainModelUnloading        unloadingModel = unloadingModels[i];
                                ICustomSerializedDomainModel serializedModel;
                                if (null != (serializedModel = unloadingModel as ICustomSerializedDomainModel))
                                {
                                    string[,] namespaceInfo = serializedModel.GetCustomElementNamespaces();
                                    int namespaceCount = namespaceInfo.GetLength(0);
                                    int j = 0;
                                    for (; j < namespaceCount; ++j)
                                    {
                                        if (checkedTypes.ContainsKey(namespaceInfo[j, 1]))
                                        {
                                            break;
                                        }
                                    }
                                    if (j == namespaceCount)
                                    {
                                        // Extension domain model is not in the pending set, go ahead and run
                                        // the custom code to unload it cleanly.
                                        if (customUnloadTransaction == null)
                                        {
                                            customUnloadTransaction = store.TransactionManager.BeginTransaction("Domain Models Unloading");                                             // String not localized, won't be displayed on either success or failure
                                        }
                                        unloadingModel.DomainModelUnloading(store);
                                    }
                                }
                            }
                        }
                    }
                    finally
                    {
                        if (customUnloadTransaction != null)
                        {
                            if (customUnloadTransaction.HasPendingChanges)
                            {
                                customUnloadTransaction.Commit();

                                // Get the modified stream
                                docDataExtender.GetAutomationObject("ORMXmlStream", null, out streamObj);
                                modifiedStream = streamObj as Stream;
                            }
                            customUnloadTransaction.Dispose();
                        }
                    }

                    newStream = ExtensionLoader.CleanupStream(modifiedStream ?? currentStream, extensionLoader.StandardDomainModels, checkedTypes.Values, null);
                    docData.ReloadFromStream(newStream, currentStream);
                }
                finally
                {
                    if (currentStream != null)
                    {
                        currentStream.Dispose();
                    }
                    if (modifiedStream != null)
                    {
                        currentStream.Dispose();
                    }
                    if (newStream != null)
                    {
                        newStream.Dispose();
                    }
                }
            }
        }