Пример #1
0
        public NodeMappingContext(int id, string[] paths, NodeMappingContext parent)
        {
            Id            = id;
            Paths         = paths;
            ParentContext = parent;

            _nodeCache = new List <IPublishedContent>();
        }
Пример #2
0
        public NodeMappingContext(int id, string[] paths, NodeMappingContext parent)
        {
            Id = id;
            Paths = paths;
            ParentContext = parent;

            _nodeCache = new List<IPublishedContent>();
        }
Пример #3
0
        public TDestination Find(int id)
        {
            var context = new NodeMappingContext(id, _paths.ToArray(), null);

            return((TDestination)_engine.Map(
                       context,
                       typeof(TDestination)
                       ));
        }
Пример #4
0
        /// <summary>
        /// Gets an Umbraco <c>Node</c> as a new instance of <typeparamref name="TDestination"/>.
        /// </summary>
        /// <typeparam name="TDestination">The type that the <c>Node</c> maps to.</typeparam>
        /// <param name="id">The ID of the <c>Node</c></param>
        /// <param name="includeRelationships">Whether to load all the <c>Node</c>'s relationships</param>
        /// <returns>
        /// <c>null</c> if the <c>Node</c> does not exist or does not map to
        /// <typeparamref name="TDestination"/>.
        /// </returns>
        /// <exception cref="MapNotFoundException">
        /// If a map for <typeparamref name="TDestination"/> has not
        /// been created with <see cref="CreateMap()" />.
        /// </exception>
        public static TDestination Find <TDestination>(int id, bool includeRelationships = true)
        {
            var paths = includeRelationships
                ? null           // all
                : new string[0]; // none

            var context = new NodeMappingContext(id, paths, null);

            return((TDestination)_engine.Map(context, typeof(TDestination)));
        }
Пример #5
0
        public object MapNode(NodeMappingContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            object destination = Activator.CreateInstance(DestinationType);

            PropertyInfo[] includedPaths = null;

            // Check included paths are actually required
            if (context.Paths != null)
            {
                includedPaths = GetImmediateProperties(DestinationType, context.Paths);

                foreach (var path in includedPaths)
                {
                    var propertyMapper = PropertyMappers.SingleOrDefault(x => x.DestinationInfo.Name == path.Name);

                    if (propertyMapper == null)
                    {
                        throw new InvalidPathException(
                                  string.Format(
                                      "The property '{0}' on '{1}' is not mapped - check your mappings.",
                                      path.Name,
                                      path.PropertyType.FullName
                                      ));
                    }
                    else if (!propertyMapper.RequiresInclude)
                    {
                        throw new InvalidPathException(
                                  string.Format(
                                      @"The property '{0}' on '{1}' does not 
require an explicit include (do not include it as a path, it will be populated automatically).",
                                      path.Name,
                                      path.PropertyType.FullName
                                      ));
                    }
                }
            }

            foreach (var propertyMapper in PropertyMappers)
            {
                if (context.Paths == null || // include all paths
                    !propertyMapper.RequiresInclude ||  // map all automatic paths
                    includedPaths.Any(x => x.Name == propertyMapper.DestinationInfo.Name))    // map explicit paths
                {
                    var destinationValue = propertyMapper.MapProperty(context);
                    propertyMapper.DestinationInfo.SetValue(destination, destinationValue, null);
                }
            }

            return(destination);
        }
Пример #6
0
        /// <summary>
        /// Gets an Umbraco <c>Node</c> as a <paramref name="destinationType"/>, only including
        /// specified relationship paths.
        /// </summary>
        /// <param name="sourceNode">The <c>Node</c> to map from.</param>
        /// <param name="destinationType">The type to map to.</param>
        /// <param name="paths">The relationship paths to include, or null to include
        /// all relationship paths at the top level and none below.</param>
        /// <returns>
        /// <c>null</c> if the node does not exist or does not map to <paramref name="destinationType"/>.
        /// </returns>
        /// <exception cref="MapNotFoundException">If a suitable map for <paramref name="destinationType"/> has not
        /// been created with <see cref="CreateMap()" />.</exception>
        public object Map(IPublishedContent sourceNode, Type destinationType, string[] paths)
        {
            if (sourceNode == null ||
                string.IsNullOrEmpty(sourceNode.Name))
            {
                return(null);
            }

            var context = new NodeMappingContext(sourceNode, paths, null);

            return(Map(context, destinationType));
        }
Пример #7
0
        public TDestination Map(IPublishedContent node)
        {
            if (node == null ||
                string.IsNullOrEmpty(node.Name))
            {
                return(null);
            }

            var context = new NodeMappingContext(node, _paths.ToArray(), null);

            return((TDestination)_engine.Map(
                       context,
                       typeof(TDestination)
                       ));
        }
Пример #8
0
        /// <summary>
        /// Maps an Umbraco <c>Node</c> to a new instance of <typeparamref name="TDestination"/>.
        /// </summary>
        /// <typeparam name="TDestination">The type to map to.</typeparam>
        /// <param name="sourceNode">The <c>Node</c> to map from.</param>
        /// <param name="includeRelationships">Whether to load relationships.</param>
        /// <returns>
        /// A new instance of <typeparamref name="TDestination"/>, or <c>null</c> if
        /// <paramref name="sourceNode"/> is <c>null</c> or does not map to
        /// <typeparamref name="TDestination"/>.
        /// </returns>
        /// <exception cref="MapNotFoundException">
        /// If a map for <typeparamref name="TDestination"/> has not
        /// been created with <see cref="CreateMap()" />.
        /// </exception>
        public static TDestination Map <TDestination>(IPublishedContent sourceNode, bool includeRelationships = true)
            where TDestination : class, new()
        {
            if (sourceNode == null || string.IsNullOrEmpty(sourceNode.Name))
            {
                return(null);
            }

            var paths = includeRelationships
                ? null           // all
                : new string[0]; // none

            var context = new NodeMappingContext(sourceNode, paths, null);

            return((TDestination)_engine.Map(context, typeof(TDestination)));
        }
Пример #9
0
        /// <summary>
        /// Gets the current Umbraco <c>Node</c> as a new instance of <typeparamref name="TDestination"/>.
        /// </summary>
        /// <typeparam name="TDestination">The type that the current <c>Node</c> maps to.</typeparam>
        /// <param name="includeRelationships">Whether to load all the <c>Node</c>'s relationships</param>
        /// <returns>
        /// <c>null</c> if there is no current <c>Node</c> or it does not map to
        /// <typeparamref name="TDestination"/>.
        /// </returns>
        /// <exception cref="MapNotFoundException">
        /// If a map for <typeparamref name="TDestination"/> has not
        /// been created with <see cref="CreateMap()" />.
        /// </exception>
        /// <seealso cref="GetSingle(int, bool)"/>
        public static TDestination GetCurrent <TDestination>(bool includeRelationships = true)
            where TDestination : class, new()
        {
            var node = UmbracoContext.Current.ContentCache.GetById(Node.getCurrentNodeId());

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

            var paths = includeRelationships
                ? null           // all
                : new string[0]; // none

            var context = new NodeMappingContext(node, paths, null);

            return((TDestination)_engine.Map(context, typeof(TDestination)));
        }
Пример #10
0
        public override object MapProperty(NodeMappingContext context)
        {
            object value = null;

            // Check cache
            if (AllowCaching
                && Engine.CacheProvider != null 
                && Engine.CacheProvider.ContainsPropertyValue(context.Id, DestinationInfo.Name))
            {
                value = Engine.CacheProvider.GetPropertyValue(context.Id, DestinationInfo.Name);
            }
            else
            {
                var node = context.GetNode();

                if (node == null || string.IsNullOrEmpty(node.Name))
                {
                    throw new InvalidOperationException("Node cannot be null or empty");
                }

                if (_mapping == null)
                {
                    // Map straight to property
                    value = GetSourcePropertyValue(node, DestinationInfo.PropertyType);
                }
                else
                {
                    // Custom mapping
                    var sourceValue = GetSourcePropertyValue(node, _sourcePropertyType);
                    value = _mapping(sourceValue);
                }

                if (AllowCaching
                    && Engine.CacheProvider != null)
                {
                    Engine.CacheProvider.InsertPropertyValue(context.Id, DestinationInfo.Name, value);
                }
            }

            return value;
        }
Пример #11
0
        /// <summary>
        /// Maps a node based on the <paramref name="context"/>.
        /// </summary>
        /// <param name="context">The context which describes the node mapping.</param>
        /// <param name="destinationType">The type to map to.</param>
        /// <returns><c>null</c> if the node does not exist.</returns>
        internal object Map(NodeMappingContext context, Type destinationType)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            else if (destinationType == null)
            {
                throw new ArgumentNullException("destinationType");
            }
            else if (!NodeMappers.ContainsKey(destinationType))
            {
                throw new MapNotFoundException(destinationType);
            }

            string sourceNodeTypeAlias = null;

            if (_cacheProvider != null &&
                _cacheProvider.ContainsAlias(context.Id))
            {
                sourceNodeTypeAlias = _cacheProvider.GetAlias(context.Id);

                if (sourceNodeTypeAlias == null)
                {
                    // Node does not exist
                    return(null);
                }
            }

            if (sourceNodeTypeAlias == null)
            {
                var node = context.GetNode();

                if (node == null || string.IsNullOrEmpty(node.Name))
                {
                    // Node doesn't exist
                    if (_cacheProvider != null)
                    {
                        _cacheProvider.InsertAlias(context.Id, null);
                    }

                    return(null);
                }

                if (_cacheProvider != null)
                {
                    _cacheProvider.InsertAlias(context.Id, node.DocumentTypeAlias);
                }

                sourceNodeTypeAlias = node.DocumentTypeAlias;
            }

            var nodeMapper = GetMapper(sourceNodeTypeAlias, destinationType);

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

            return(nodeMapper.MapNode(context));
        }
        public override object MapProperty(NodeMappingContext context)
        {
            IEnumerable<int> ids = null;

            // Get IDs
            if (AllowCaching
                && Engine.CacheProvider != null
                && Engine.CacheProvider.ContainsPropertyValue(context.Id, DestinationInfo.Name))
            {
                ids = Engine.CacheProvider.GetPropertyValue(context.Id, DestinationInfo.Name) as int[];
            }
            else
            {
                var node = context.GetNode();

                if (node == null || string.IsNullOrEmpty(node.Name))
                {
                    throw new InvalidOperationException("Node cannot be null or empty");
                }

                if (string.IsNullOrEmpty(SourcePropertyAlias))
                {
                    // Get compatible descendants
                    var aliases = Engine.GetCompatibleNodeTypeAliases(_elementType);

                    var nodes = aliases.SelectMany(alias => node.Descendants(alias));

                    // Might as well store the nodes if we're creating them
                    foreach (var n in nodes)
                    {
                        context.AddNodeToContextCache(n);
                    }

                    ids = nodes.Select(n => n.Id);

                    if (_mapping != null)
                    {
                        ids = _mapping(context, ids);
                    }
                }
                else
                {
                    if (_mapping == null)
                    {
                        // Maps IDs from node property
                        ids = GetSourcePropertyValue<IEnumerable<int>>(node);
                    }
                    else
                    {
                        // Custom mapping
                        ids = _mapping(context, GetSourcePropertyValue(node, _sourcePropertyType));
                    }
                }
            }

            if (_elementType == typeof(int))
            {
                // Map ID collection
                return _canAssignDirectly
                    ? ids
                    : Activator.CreateInstance(DestinationInfo.PropertyType, ids);
            }

            // Map model collection
            var childPaths = GetNextLevelPaths(context.Paths);
            var sourceListType = typeof(List<>).MakeGenericType(_elementType);
            var mappedCollection = Activator.CreateInstance(sourceListType);
            var missingIds = new List<int>();

            foreach (var id in ids)
            {
                var childContext = new NodeMappingContext(id, childPaths, context);
                var mappedElement = Engine.Map(childContext, _elementType);

                if (mappedElement == null)
                {
                    // ID does not exist
                    missingIds.Add(id);
                }
                else
                {
                    // Like "items.Add(item)" but for generic list
                    sourceListType.InvokeMember("Add", BindingFlags.InvokeMethod, null, mappedCollection, new object[] { mappedElement });
                }
            }

            if (AllowCaching
                && Engine.CacheProvider != null)
            {
                Engine.CacheProvider.InsertPropertyValue(context.Id, DestinationInfo.Name, ids.Except(missingIds).ToArray());
            }

            return _canAssignDirectly
                ? mappedCollection
                : Activator.CreateInstance(DestinationInfo.PropertyType, mappedCollection);
        }
Пример #13
0
 public NodeMappingContext(IPublishedContent node, string[] paths, NodeMappingContext parent)
     : this(node.Id, paths, parent)
 {
     _nodeCache.Add(node);
 }
Пример #14
0
        public object MapNode(NodeMappingContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            object destination = Activator.CreateInstance(DestinationType);

            PropertyInfo[] includedPaths = null;

            // Check included paths are actually required
            if (context.Paths != null)
            {
                includedPaths = GetImmediateProperties(DestinationType, context.Paths);

                foreach (var path in includedPaths)
                {
                    var propertyMapper = PropertyMappers.SingleOrDefault(x => x.DestinationInfo.Name == path.Name);

                    if (propertyMapper == null)
                    {
                        throw new InvalidPathException(
                            string.Format(
                                "The property '{0}' on '{1}' is not mapped - check your mappings.",
                                path.Name,
                                path.PropertyType.FullName
                                ));
                    }
                    else if (!propertyMapper.RequiresInclude)
                    {
                        throw new InvalidPathException(
                            string.Format(
                                @"The property '{0}' on '{1}' does not 
require an explicit include (do not include it as a path, it will be populated automatically).",
                                path.Name,
                                path.PropertyType.FullName
                                ));
                    }
                }
            }

            foreach (var propertyMapper in PropertyMappers)
            {
                if (context.Paths == null // include all paths
                    || !propertyMapper.RequiresInclude  // map all automatic paths
                    || includedPaths.Any(x => x.Name == propertyMapper.DestinationInfo.Name)) // map explicit paths
                {
                    var destinationValue = propertyMapper.MapProperty(context);
                    propertyMapper.DestinationInfo.SetValue(destination, destinationValue, null);
                }
            }

            return destination;
        }
Пример #15
0
 public NodeMappingContext(IPublishedContent node, string[] paths, NodeMappingContext parent)
     : this(node.Id, paths, parent)
 {
     _nodeCache.Add(node);
 }