Ejemplo 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);
        }