1 //---------------------------------------------------------------------
2 // <copyright file="MetadataArtifactLoaderResource.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
7 // @backupOwner Microsoft
8 //---------------------------------------------------------------------
10 namespace System.Data.Metadata.Edm
12 using System.Collections.Generic;
13 using System.Data.EntityModel.SchemaObjectModel;
14 using System.Diagnostics;
16 using System.Reflection;
20 /// This class represents one resource item to be loaded from an assembly.
22 internal class MetadataArtifactLoaderResource : MetadataArtifactLoader, IComparable
24 private readonly bool _alreadyLoaded = false;
25 private readonly Assembly _assembly;
26 private readonly string _resourceName;
29 /// Constructor - loads the resource stream
31 /// <param name="path">The path to the resource to load</param>
32 /// <param name="uriRegistry">The global registry of URIs</param>
33 internal MetadataArtifactLoaderResource(Assembly assembly, string resourceName, ICollection<string> uriRegistry)
35 Debug.Assert(assembly != null);
36 Debug.Assert(resourceName != null);
39 _resourceName = resourceName;
41 string tempPath = MetadataArtifactLoaderCompositeResource.CreateResPath(_assembly, _resourceName);
42 _alreadyLoaded = uriRegistry.Contains(tempPath);
45 uriRegistry.Add(tempPath);
47 // '_alreadyLoaded' is not set because while we would like to prevent
48 // other instances of MetadataArtifactLoaderFile that wrap the same
49 // _path from being added to the list of paths/readers, we do want to
50 // include this particular instance.
54 public override string Path
58 return MetadataArtifactLoaderCompositeResource.CreateResPath(_assembly, _resourceName);
63 /// Implementation of IComparable.CompareTo()
65 /// <param name="obj">The object to compare to</param>
66 /// <returns>0 if the loaders are "equal" (i.e., have the same _path value)</returns>
67 public int CompareTo(object obj)
69 MetadataArtifactLoaderResource loader = obj as MetadataArtifactLoaderResource;
72 return string.Compare(Path, loader.Path, StringComparison.OrdinalIgnoreCase);
75 Debug.Assert(false, "object is not a MetadataArtifactLoaderResource");
80 /// Equals() returns true if the objects have the same _path value
82 /// <param name="obj">The object to compare to</param>
83 /// <returns>true if the objects have the same _path value</returns>
84 public override bool Equals(object obj)
86 return this.CompareTo(obj) == 0;
90 /// GetHashCode override that defers the result to the _path member variable.
92 /// <returns></returns>
93 public override int GetHashCode()
95 return Path.GetHashCode();
98 public override void CollectFilePermissionPaths(List<string> paths, DataSpace spaceToGet)
104 /// Get paths to artifacts for a specific DataSpace.
106 /// <param name="spaceToGet">The DataSpace for the artifacts of interest</param>
107 /// <returns>A List of strings identifying paths to all artifacts for a specific DataSpace</returns>
108 public override List<string> GetPaths(DataSpace spaceToGet)
110 List<string> list = new List<string>();
111 if (!_alreadyLoaded && MetadataArtifactLoader.IsArtifactOfDataSpace(Path, spaceToGet))
119 /// Get paths to all artifacts
121 /// <returns>A List of strings identifying paths to all resources</returns>
122 public override List<string> GetPaths()
124 List<string> list = new List<string>();
133 /// Create and return an XmlReader around the resource represented by this instance.
135 /// <returns>A List of XmlReaders for all resources</returns>
136 public override List<XmlReader> GetReaders(Dictionary<MetadataArtifactLoader, XmlReader> sourceDictionary)
138 List<XmlReader> list = new List<XmlReader>();
142 XmlReader reader = CreateReader();
145 if (sourceDictionary != null)
147 sourceDictionary.Add(this, reader);
153 private XmlReader CreateReader()
156 Stream stream = LoadResource();
158 XmlReaderSettings readerSettings = Schema.CreateEdmStandardXmlReaderSettings();
159 // close the stream when the xmlreader is closed
160 // now the reader owns the stream
161 readerSettings.CloseInput = true;
163 // we know that we aren't reading a fragment
164 readerSettings.ConformanceLevel = ConformanceLevel.Document;
165 XmlReader reader = XmlReader.Create(stream, readerSettings);
166 // cannot set the base URI because res:// URIs cause the schema parser
173 /// Create and return an XmlReader around the resource represented by this instance
174 /// if it is of the requested DataSpace type.
176 /// <param name="spaceToGet">The DataSpace corresponding to the requested artifacts</param>
177 /// <returns>A List of XmlReader objects</returns>
178 public override List<XmlReader> CreateReaders(DataSpace spaceToGet)
180 List<XmlReader> list = new List<XmlReader>();
183 if (MetadataArtifactLoader.IsArtifactOfDataSpace(Path, spaceToGet))
185 XmlReader reader = CreateReader();
193 /// This method parses the path to the resource and attempts to load it.
194 /// The method also accounts for the wildcard assembly name.
196 private Stream LoadResource()
198 Stream resourceStream;
199 if (TryCreateResourceStream(out resourceStream))
201 return resourceStream;
203 throw EntityUtil.Metadata(System.Data.Entity.Strings.UnableToLoadResource);
206 private bool TryCreateResourceStream(out Stream resourceStream)
208 resourceStream = _assembly.GetManifestResourceStream(_resourceName);
209 return resourceStream != null;