/// <summary>
        /// Creates if necessary the base type and update the base type list of the specified type
        /// </summary>
        /// <param name="baseTypeName">Base type name to create and add</param>
        /// <param name="type">The type whose base type list needs updating</param>
        /// <param name="isExistingType">Whether the type is a new type or existent one</param>
        private void AddBaseTypeOfType(string baseTypeName, ContentTypeImpl type, bool isExistingType)
        {
            if (baseTypeName != null)
            {
                string uppercaseBaseTypeName = baseTypeName.ToUpperInvariant();

                // no content type can derive from unknown
                // Do this check before GetOrCreateContentType because it provides a more meaningful exception message
                if (baseTypeName == ContentTypeRegistryImpl.UnknownContentTypeName)
                {
                    throw new InvalidOperationException(String.Format(System.Globalization.CultureInfo.CurrentUICulture,
                                                                      Strings.ContentTypeRegistry_ContentTypesCannotDeriveFromUnknown, type.TypeName));
                }

                // Get existing or create new base content type if any base type is specified
                ContentTypeImpl baseType;
                bool            isExistingBaseType = GetOrCreateContentType(baseTypeName, out baseType);

                // Only a new mapping between two existing nodes can introduce a cycle in the graph.
                if (isExistingType && isExistingBaseType && this.CausesCycle(type, baseType))
                {
                    throw new InvalidOperationException(String.Format(System.Globalization.CultureInfo.CurrentUICulture, Strings.ContentTypeRegistry_CausesCycles, baseType.TypeName, type.TypeName));
                }

                if (!isExistingBaseType)
                {
                    this.contentTypes.Add(uppercaseBaseTypeName, baseType);
                }

                type.AddBaseType(baseType);
            }
        }
        /// <summary>
        /// Creates and adds a new content type with the specified name, or returns the existing type
        /// </summary>
        /// <param name="typeName"></param>
        /// <param name="type">The type created or existent</param>
        /// <returns>true if the type already existed</returns>
        private bool GetOrCreateContentType(string typeName, out ContentTypeImpl type)
        {
            // Get existing or create new content type
            if (string.IsNullOrEmpty(typeName))
            {
                throw new ArgumentException(Strings.ContentTypeRegistry_CannotAddTypeWithEmptyTypeName);
            }

            string uppercaseTypeName = typeName.ToUpperInvariant();

            // no one can produce another unknown content type
            if (uppercaseTypeName == ContentTypeRegistryImpl.UnknownContentTypeName)
            {
                throw new InvalidOperationException(Strings.ContentTypeRegistry_CannotProduceAnotherUnknownType);
            }

            bool isExistingType = this.contentTypes.TryGetValue(uppercaseTypeName, out type);

            if (!isExistingType)
            {
                type = new ContentTypeImpl(typeName);
            }

            return(isExistingType);
        }
예제 #3
0
 internal void AddBaseType(ContentTypeImpl baseType)
 {
     // TODO: should be part of ctor; this class should be invariant
     if (!this.BaseTypeList.Contains(baseType))
     {
         this.BaseTypeList.Add(baseType);
     }
 }
        public IContentType GetContentType(string typeName)
        {
            Requires.NotNullOrWhiteSpace(typeName, nameof(typeName));

            this.BuildContentTypes();

            ContentTypeImpl contentType = null;

            this.maps.NameToContentTypeMap.TryGetValue(typeName, out contentType);

            return(contentType);
        }
        public IContentType GetContentType(string typeName)
        {
            ContentTypeImpl contentType = null;

            lock (this.syncLock)
            {
                this.BuildContentTypes();
                this.contentTypes.TryGetValue(typeName.ToUpperInvariant(), out contentType);
            }

            return(contentType);
        }
예제 #6
0
        public IContentType GetContentType(string typeName)
        {
            if (string.IsNullOrWhiteSpace(typeName))
            {
                throw new ArgumentException(nameof(typeName));
            }

            this.BuildContentTypes();

            ContentTypeImpl contentType = null;

            this.maps.NameToContentTypeMap.TryGetValue(typeName, out contentType);

            return(contentType);
        }
예제 #7
0
        public IContentType GetContentTypeForFileName(string fileName)
        {
            if (fileName == null)
            {
                throw new ArgumentNullException(nameof(fileName));
            }

            this.BuildContentTypes();

            ContentTypeImpl contentType = null;

            this.maps.FileNameToContentTypeMap.TryGetValue(fileName, out contentType);

            // TODO: should we return null if contentType is null?
            return(contentType ?? ContentTypeRegistryImpl.UnknownContentTypeImpl);
        }
예제 #8
0
        public IContentType GetContentTypeForExtension(string extension)
        {
            if (extension == null)
            {
                throw new ArgumentNullException(nameof(extension));
            }

            this.BuildContentTypes();

            ContentTypeImpl contentType = null;

            this.maps.FileExtensionToContentTypeMap.TryGetValue(RemoveExtensionDot(extension), out contentType);

            // TODO: should we return null if contentType is null?
            return(contentType ?? ContentTypeRegistryImpl.UnknownContentTypeImpl);
        }
        public void RemoveContentType(string typeName)
        {
            lock (this.syncLock)
            {
                // Make sure first the content type map is built
                BuildContentTypes();
            }

            // Since file extension registry will call back the content type registry when it gets initialized,
            // make sure we force the initialization before obtaining the lock. This will guarantee we won't deadlock
            // when we'll ask the registered extension later, after we obtained the content types lock
            FileExtensionRegistry.GetContentTypeForExtension("");
            string uppercaseTypeName = typeName.ToUpperInvariant();

            lock (this.syncLock)
            {
                ContentTypeImpl type = null;
                if (!this.contentTypes.TryGetValue(uppercaseTypeName, out type))
                {
                    // If the type was not registered, removal is successful
                    return;
                }

                // Check if the type to be removed is not the Unknown content type
                if (uppercaseTypeName == ContentTypeRegistryImpl.UnknownContentTypeName)
                {
                    throw new InvalidOperationException(Strings.ContentTypeRegistry_CannotRemoveTheUnknownType);
                }

                // Check if the type is base type for another registered type
                ContentTypeImpl derivedType;
                if (IsBaseType(type, out derivedType))
                {
                    throw new InvalidOperationException(String.Format(System.Globalization.CultureInfo.CurrentUICulture, Strings.ContentTypeRegistry_CannotRemoveBaseType, type.TypeName, derivedType.TypeName));
                }

                // If there are file extensions using this content type we won't allow removing it
                IEnumerable <string> extensions = FileExtensionRegistry.GetExtensionsForContentType(type);
                if (extensions != null && extensions.GetEnumerator().MoveNext())
                {
                    throw new InvalidOperationException(String.Format(System.Globalization.CultureInfo.CurrentUICulture, Strings.ContentTypeRegistry_CannotRemoveTypeUsedByFileExtensions, type.TypeName));
                }

                // Remove the content type
                this.contentTypes.Remove(uppercaseTypeName);
            }
        }
        public IContentType GetContentTypeForFileName(string fileName)
        {
            ContentTypeImpl contentType = null;

            if (string.IsNullOrWhiteSpace(fileName))
            {
                if (fileName == null)
                {
                    throw new ArgumentNullException(nameof(fileName));
                }
            }
            else
            {
                this.BuildContentTypes();
                this.maps.FileNameToContentTypeMap.TryGetValue(fileName, out contentType);
            }

            return(contentType ?? ContentTypeRegistryImpl.UnknownContentTypeImpl);
        }
        public IContentType GetContentTypeForExtension(string extension)
        {
            ContentTypeImpl contentType = null;

            if (string.IsNullOrEmpty(extension))
            {
                if (extension == null)
                {
                    throw new ArgumentNullException(nameof(extension));
                }
            }
            else
            {
                this.BuildContentTypes();
                this.maps.FileExtensionToContentTypeMap.TryGetValue(RemoveExtensionDot(extension), out contentType);
            }

            return(contentType ?? ContentTypeRegistryImpl.UnknownContentTypeImpl);
        }
예제 #12
0
        internal static ContentTypeImpl AddContentTypeFromMetadata(string contentTypeName, string mimeType, IEnumerable <string> baseTypes,
                                                                   IDictionary <string, ContentTypeImpl> nameToContentTypeBuilder,
                                                                   IDictionary <string, ContentTypeImpl> mimeTypeToContentTypeBuilder)
        {
            if (!string.IsNullOrEmpty(contentTypeName))
            {
                ContentTypeImpl type;
                if (!nameToContentTypeBuilder.TryGetValue(contentTypeName, out type))
                {
                    bool addToMimeTypeMap = false;
                    if (string.IsNullOrWhiteSpace(mimeType))
                    {
                        mimeType = MimePrefix + contentTypeName.ToLowerInvariant();
                    }
                    else if (mimeTypeToContentTypeBuilder.ContainsKey(mimeType))
                    {
                        mimeType = null;
                    }
                    else
                    {
                        addToMimeTypeMap = true;
                    }

                    type = new ContentTypeImpl(contentTypeName, mimeType, baseTypes);

                    nameToContentTypeBuilder.Add(contentTypeName, type);
                    if (addToMimeTypeMap)
                    {
                        mimeTypeToContentTypeBuilder.Add(mimeType, type);
                    }
                }
                else
                {
                    type.AddUnprocessedBaseTypes(baseTypes);
                }

                return(type);
            }

            return(null);
        }
예제 #13
0
        /// <summary>
        /// Checks whether the specified type is base type for another content type
        /// </summary>
        /// <param name="typeToCheck">The type to check for being a base type</param>
        /// <param name="derivedType">An out parameter to receive the first discovered derived type</param>
        /// <returns><c>True</c> if the given <paramref name="typeToCheck"/> content type is a base type</returns>
        private bool IsBaseType(ContentTypeImpl typeToCheck, out ContentTypeImpl derivedType)
        {
            derivedType = null;

            foreach (ContentTypeImpl type in this.maps.NameToContentTypeMap.Values)
            {
                if (type != typeToCheck)
                {
                    foreach (IContentType baseType in type.BaseTypes)
                    {
                        if (baseType == typeToCheck)
                        {
                            derivedType = type;
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
        public IContentType GetContentTypeForMimeType(string mimeType)
        {
            Requires.NotNullOrWhiteSpace(mimeType, nameof(mimeType));

            this.BuildContentTypes();

            ContentTypeImpl contentType = null;

            if (!this.maps.MimeTypeToContentTypeMap.TryGetValue(mimeType, out contentType))
            {
                if (mimeType.StartsWith(BaseMimePrefix, StringComparison.Ordinal))
                {
                    if (!(mimeType.StartsWith(MimePrefix, StringComparison.Ordinal) && this.maps.NameToContentTypeMap.TryGetValue(mimeType.Substring(MimePrefix.Length), out contentType)))
                    {
                        this.maps.NameToContentTypeMap.TryGetValue(mimeType.Substring(BaseMimePrefix.Length), out contentType);
                    }
                }
            }

            return(contentType);
        }
        /// <summary>
        /// Checks whether the specified type is base type for another content type
        /// </summary>
        /// <param name="typeToCheck">The type to check for being a base type</param>
        /// <param name="derivedType">An out parameter to receive the first discovered derived type</param>
        /// <returns><c>True</c> if the given <paramref name="typeToCheck"/> content type is a base type</returns>
        private bool IsBaseType(ContentTypeImpl typeToCheck, out ContentTypeImpl derivedType)
        {
            derivedType = null;

            foreach (ContentTypeImpl type in contentTypes.Values)
            {
                if (type != typeToCheck)
                {
                    foreach (IContentType baseType in type.BaseTypes)
                    {
                        if (String.Compare(baseType.TypeName, typeToCheck.TypeName, StringComparison.OrdinalIgnoreCase) == 0)
                        {
                            derivedType = type;
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
예제 #16
0
        public IContentType GetContentTypeForMimeType(string mimeType)
        {
            if (string.IsNullOrWhiteSpace(mimeType))
            {
                throw new ArgumentException(nameof(mimeType));
            }

            this.BuildContentTypes();

            ContentTypeImpl contentType = null;

            if (!this.maps.MimeTypeToContentTypeMap.TryGetValue(mimeType, out contentType))
            {
                if (mimeType.StartsWith(BaseMimePrefix))
                {
                    if (!(mimeType.StartsWith(MimePrefix) && this.maps.NameToContentTypeMap.TryGetValue(mimeType.Substring(MimePrefix.Length), out contentType)))
                    {
                        this.maps.NameToContentTypeMap.TryGetValue(mimeType.Substring(BaseMimePrefix.Length), out contentType);
                    }
                }
            }

            return(contentType);
        }