Ejemplo n.º 1
0
        /// <summary>
        /// Gets an <see cref="Rock.Model.EntityType" /> by its name. If a match is not found, a new <see cref="Rock.Model.EntityType" /> can optionally be created.
        /// </summary>
        /// <param name="name">A <see cref="System.String" /> representing the name of the object/entity type to search for.</param>
        /// <param name="createIfNotFound">A <see cref="System.Boolean" /> value that indicates if a new <see cref="Rock.Model.EntityType" /> should be created if a match is not found. This value
        /// will be <c>true</c> if a new <see cref="Rock.Model.EntityType" /> should be created if there is not a match; otherwise <c>false</c>/</param>
        /// <returns></returns>
        public EntityType GetByName(string name, bool createIfNotFound)
        {
            var entityType = Get(name);

            if (entityType != null)
            {
                return(entityType);
            }

            if (createIfNotFound)
            {
                // Create a new context so type can be saved independing of current context
                var rockContext       = new RockContext();
                var entityTypeService = new EntityTypeService(rockContext);
                entityType      = new EntityType();
                entityType.Name = name;
                entityTypeService.Add(entityType);
                rockContext.SaveChanges();

                // Read type using current context
                return(this.Get(entityType.Id));
            }

            return(null);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Gets the specified <see cref="Rock.Model.EntityType"/> by the object type. If a match is not found, it can optionally create a new <see cref="Rock.Model.EntityType"/> for the object.
        /// </summary>
        /// <param name="type">The <see cref="System.Type"/> to search for.</param>
        /// <param name="createIfNotFound">A <see cref="System.Boolean"/> value that indicates if a new <see cref="Rock.Model.EntityType"/> should be created if a match is not found. This value
        /// will be <c>true</c> if a new <see cref="Rock.Model.EntityType"/> should be created if there is not a match; otherwise <c>false</c>/</param>
        /// <param name="personAlias">A <see cref="Rock.Model.PersonAlias"/> representing the alias of the <see cref="Rock.Model.Person"/> who is searching for and possibly creating a new EntityType.  This value can be
        /// null if the logged in person is not known (i.e. an anonymous user).</param>
        /// <returns>A <see cref="Rock.Model.EntityType"/> matching the provided type. If a match is not found and createIfNotFound is false this value will be null.</returns>
        public EntityType Get(Type type, bool createIfNotFound, PersonAlias personAlias)
        {
            var entityType = Get(type.FullName);

            if (entityType != null)
            {
                return(entityType);
            }

            if (createIfNotFound)
            {
                // Create a new context so type can be saved independing of current context
                using (var rockContext = new RockContext())
                {
                    var entityTypeService = new EntityTypeService(rockContext);
                    entityType              = new EntityType();
                    entityType.Name         = type.FullName;
                    entityType.FriendlyName = type.Name.SplitCase();
                    entityType.AssemblyName = type.AssemblyQualifiedName;
                    entityTypeService.Add(entityType);
                    rockContext.SaveChanges();
                }

                // Read type using current context
                return(this.Get(entityType.Id));
            }

            return(null);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Handles the SaveClick event of the mdEdit control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        protected void mdEdit_SaveClick( object sender, EventArgs e )
        {
            var rockContext = new RockContext();
            EntityTypeService entityTypeService = new EntityTypeService( rockContext );
            EntityType entityType = entityTypeService.Get( int.Parse( hfEntityTypeId.Value ) );

            if ( entityType == null )
            {
                entityType = new EntityType();
                entityType.IsEntity = true;
                entityType.IsSecured = true;
                entityTypeService.Add( entityType );
            }

            entityType.Name = tbName.Text;
            entityType.FriendlyName = tbFriendlyName.Text;
            entityType.IsCommon = cbCommon.Checked;

            rockContext.SaveChanges();

            EntityTypeCache.Flush( entityType.Id );

            hfEntityTypeId.Value = string.Empty;

            HideDialog();

            BindGrid();
        }
        /// <summary>
        /// Gets the specified <see cref="Rock.Model.EntityType"/> by the object type. If a match is not found, it can optionally create a new <see cref="Rock.Model.EntityType"/> for the object.
        /// </summary>
        /// <param name="type">The <see cref="System.Type"/> to search for.</param>
        /// <param name="createIfNotFound">A <see cref="System.Boolean"/> value that indicates if a new <see cref="Rock.Model.EntityType"/> should be created if a match is not found. This value
        /// will be <c>true</c> if a new <see cref="Rock.Model.EntityType"/> should be created if there is not a match; otherwise <c>false</c>/</param>
        /// <param name="personAlias">A <see cref="Rock.Model.PersonAlias"/> representing the alias of the <see cref="Rock.Model.Person"/> who is searching for and possibly creating a new EntityType.  This value can be
        /// null if the logged in person is not known (i.e. an anonymous user).</param>
        /// <returns>A <see cref="Rock.Model.EntityType"/> matching the provided type. If a match is not found and createIfNotFound is false this value will be null.</returns>
        public EntityType Get( Type type, bool createIfNotFound, PersonAlias personAlias )
        {
            var entityType = Get( type.FullName );
            if ( entityType != null )
            {
                return entityType;
            }

            if ( createIfNotFound )
            {
                // Create a new context so type can be saved independing of current context
                using ( var rockContext = new RockContext() )
                {
                    var EntityTypeService = new EntityTypeService( rockContext );
                    entityType = new EntityType();
                    entityType.Name = type.FullName;
                    entityType.FriendlyName = type.Name.SplitCase();
                    entityType.AssemblyName = type.AssemblyQualifiedName;
                    EntityTypeService.Add( entityType );
                    rockContext.SaveChanges();
                }

                // Read type using current context
                return this.Get( entityType.Id );
            }

            return null;
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Gets a list of ISecured and IEntity entities (all models) that have not yet been registered and adds them
        /// as an <see cref="Rock.Model.EntityType"/>.
        /// </summary>
        /// <param name="physWebAppPath">A <see cref="System.String"/> that represents the physical path of the web application</param>
        public static void RegisterEntityTypes( string physWebAppPath )
        {
            var entityTypes = new Dictionary<string, EntityType>();

            foreach ( var type in Rock.Reflection.FindTypes( typeof( Rock.Data.IEntity ) ) )
            {
                var entityType = new EntityType();
                entityType.Name = type.Key;
                entityType.FriendlyName = type.Value.Name.SplitCase();
                entityType.AssemblyName = type.Value.AssemblyQualifiedName;
                entityType.IsEntity = !type.Value.GetCustomAttributes( typeof(System.ComponentModel.DataAnnotations.Schema.NotMappedAttribute), false ).Any();
                entityType.IsSecured = false;
                entityTypes.Add( type.Key.ToLower(), entityType );
            }

            foreach ( var type in Rock.Reflection.FindTypes( typeof( Rock.Security.ISecured ) ) )
            {
                string key = type.Key.ToLower();

                if ( entityTypes.ContainsKey( key ) )
                {
                    entityTypes[key].IsSecured = true;
                }
                else
                {
                    var entityType = new EntityType();
                    entityType.Name = type.Key;
                    entityType.FriendlyName = type.Value.Name.SplitCase();
                    entityType.AssemblyName = type.Value.AssemblyQualifiedName;
                    entityType.IsEntity = false;
                    entityType.IsSecured = true;
                    entityTypes.Add( key, entityType );
                }
            }

            using ( var rockContext = new RockContext() )
            {
                var entityTypeService = new EntityTypeService( rockContext );

                // Find any existing EntityTypes marked as an entity or secured that are no longer an entity or secured
                foreach ( var oldEntityType in entityTypeService.Queryable()
                    .Where( e => e.IsEntity || e.IsSecured )
                    .ToList() )
                {
                    if ( !entityTypes.Keys.Contains( oldEntityType.Name.ToLower() ) )
                    {
                        oldEntityType.IsSecured = false;
                        oldEntityType.IsEntity = false;
                        oldEntityType.AssemblyName = null;
                        EntityTypeCache.Flush( oldEntityType.Id );
                    }
                }

                // Update any existing entities
                foreach ( var existingEntityType in entityTypeService.Queryable()
                    .Where( e => entityTypes.Keys.Contains( e.Name ) )
                    .ToList() )
                {
                    var key = existingEntityType.Name.ToLower();

                    var entityType = entityTypes[key];

                    if ( existingEntityType.Name != entityType.Name ||
                        existingEntityType.IsEntity != entityType.IsEntity ||
                        existingEntityType.IsSecured != entityType.IsSecured ||
                        existingEntityType.FriendlyName != ( existingEntityType.FriendlyName ?? entityType.FriendlyName ) ||
                        existingEntityType.AssemblyName != entityType.AssemblyName )
                    {
                        existingEntityType.Name = entityType.Name;
                        existingEntityType.IsEntity = entityType.IsEntity;
                        existingEntityType.IsSecured = entityType.IsSecured;
                        existingEntityType.FriendlyName = existingEntityType.FriendlyName ?? entityType.FriendlyName;
                        existingEntityType.AssemblyName = entityType.AssemblyName;
                        EntityTypeCache.Flush( existingEntityType.Id );
                    }
                    entityTypes.Remove( key );
                }

                // Add the newly discovered entities
                foreach ( var entityTypeInfo in entityTypes )
                {
                    // Don't add the EntityType entity as it will probably have been automatically
                    // added by the audit on a previous save in this method.
                    if ( entityTypeInfo.Value.Name != "Rock.Model.EntityType" )
                    {
                        entityTypeService.Add( entityTypeInfo.Value );
                    }
                }

                rockContext.SaveChanges();

                // make sure the EntityTypeCache is synced up with any changes that were made
                foreach (var entityTypeModel in entityTypeService.Queryable())
                {
                    EntityTypeCache.Read( entityTypeModel );
                }
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Gets an <see cref="Rock.Model.EntityType" /> by its name. If a match is not found, a new <see cref="Rock.Model.EntityType" /> can optionally be created.
        /// </summary>
        /// <param name="name">A <see cref="System.String" /> representing the name of the object/entity type to search for.</param>
        /// <param name="createIfNotFound">A <see cref="System.Boolean" /> value that indicates if a new <see cref="Rock.Model.EntityType" /> should be created if a match is not found. This value
        /// will be <c>true</c> if a new <see cref="Rock.Model.EntityType" /> should be created if there is not a match; otherwise <c>false</c>/</param>
        /// <returns></returns>
        public EntityType Get( string name, bool createIfNotFound )
        {
            var entityType = Get( name );
            if ( entityType != null )
            {
                return entityType;
            }

            if ( createIfNotFound )
            {
                // Create a new context so type can be saved independing of current context
                var rockContext = new RockContext();
                var EntityTypeService = new EntityTypeService( rockContext );
                entityType = new EntityType();
                entityType.Name = name;
                EntityTypeService.Add( entityType );
                rockContext.SaveChanges();

                // Read type using current context
                return this.Get( entityType.Id );
            }

            return null;
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Uses Reflection to find all IEntity entities (all models), ISecured Types (could be a model or a component), and IRockBlockTypes.
        /// Then ensures that the <seealso cref="Rock.Model.EntityType" /> table is synced up to match.
        /// </summary>
        public static void RegisterEntityTypes()
        {
            List <Type> reflectedTypes = new List <Type>();

            // we'll auto-register anything that implements IEntity, ISecured or IRockBlockType
            reflectedTypes.AddRange(Rock.Reflection.FindTypes(typeof(Rock.Data.IEntity)).Values);
            reflectedTypes.AddRange(Rock.Reflection.FindTypes(typeof(Rock.Security.ISecured)).Values);
            reflectedTypes.AddRange(Rock.Reflection.FindTypes(typeof(Rock.Blocks.IRockBlockType)).Values);

            // do a distinct since some of the types implement both IEntity and ISecured
            reflectedTypes = reflectedTypes.Distinct().OrderBy(a => a.FullName).ToList();

            Dictionary <string, EntityType> entityTypesFromReflection = new Dictionary <string, EntityType>(StringComparer.OrdinalIgnoreCase);

            foreach (var reflectedType in reflectedTypes)
            {
                var entityType = new EntityType();
                entityType.Name         = reflectedType.FullName;
                entityType.FriendlyName = reflectedType.Name.SplitCase();
                entityType.AssemblyName = reflectedType.AssemblyQualifiedName;
                if (typeof(IEntity).IsAssignableFrom(reflectedType))
                {
                    entityType.IsEntity = reflectedType.GetCustomAttribute <System.ComponentModel.DataAnnotations.Schema.NotMappedAttribute>() == null;
                }
                else
                {
                    entityType.IsEntity = false;
                }

                entityType.IsSecured = typeof(Rock.Security.ISecured).IsAssignableFrom(reflectedType);

                entityTypesFromReflection.AddOrIgnore(reflectedType.FullName, entityType);
            }
            ;

            using (var rockContext = new RockContext())
            {
                var entityTypeService = new EntityTypeService(rockContext);

                var reflectedTypeNames = reflectedTypes.Select(a => a.FullName).ToArray();

                // Get all the EntityType records from the Database without filtering them (we'll have to deal with them all)
                // Then we'll split them into a list of ones that don't exist and ones that still exist
                var entityTypeInDatabaseList = entityTypeService.Queryable().ToList();

                // Find any existing self-discovered EntityType records that no longer exist in reflectedTypes
                // but have C# narrow it down to ones that aren't in the reflectedTypeNames list
                var reflectedEntityTypesThatNoLongerExist = entityTypeInDatabaseList
                                                            .Where(e => !string.IsNullOrEmpty(e.AssemblyName))
                                                            .ToList()
                                                            .Where(e => !reflectedTypeNames.Contains(e.Name))
                                                            .OrderBy(a => a.Name)
                                                            .ToList();

                // clean up entitytypes that don't have an Assembly, but somehow have IsEntity or IsSecured set
                foreach (var entityTypesWithoutAssembliesButIsEntity in entityTypeInDatabaseList.Where(e => string.IsNullOrEmpty(e.AssemblyName) && (e.IsEntity || e.IsSecured)))
                {
                    if (entityTypesWithoutAssembliesButIsEntity.AssemblyName.IsNullOrWhiteSpace())
                    {
                        entityTypesWithoutAssembliesButIsEntity.IsEntity  = false;
                        entityTypesWithoutAssembliesButIsEntity.IsSecured = false;
                    }
                }

                foreach (var oldEntityType in reflectedEntityTypesThatNoLongerExist)
                {
                    Type foundType = null;
                    // if this isn't one of the EntityTypes that we self-register,
                    // see if it was manually registered first (with EntityTypeCache.Get(Type type, bool createIfNotExists))
                    try
                    {
                        foundType = Type.GetType(oldEntityType.AssemblyName, false);
                    }
                    catch
                    {
                        /* 2020-05-22 MDP
                         * GetType (string typeName, bool throwOnError) can throw exceptions even if throwOnError is false!
                         * see https://docs.microsoft.com/en-us/dotnet/api/system.type.gettype?view=netframework-4.5.2#System_Type_GetType_System_String_System_Boolean_
                         *
                         * so, if this happens, we'll ignore any error it returns in those cases too
                         */
                    }

                    if (foundType == null)
                    {
                        // it was manually registered but we can't create a Type from it
                        // so we'll update the EntityType.AssemblyName to null
                        // and set IsSecured and IsEntity to False (since a NULL type doesn't implement ISecured or IEntity)
                        oldEntityType.AssemblyName = null;
                        oldEntityType.IsSecured    = false;
                        oldEntityType.IsEntity     = false;
                    }
                }

                // Now get the entityType records that are still in the list of types we found thru reflection
                // but we'll have C# narrow it down to ones that aren't in the reflectedTypeNames list
                var reflectedEntityTypesThatStillExist = entityTypeInDatabaseList
                                                         .Where(e => reflectedTypeNames.Contains(e.Name))
                                                         .ToList();

                // Update any existing entities
                foreach (var existingEntityType in reflectedEntityTypesThatStillExist)
                {
                    var entityTypeFromReflection = entityTypesFromReflection.GetValueOrNull(existingEntityType.Name);
                    if (entityTypeFromReflection == null)
                    {
                        continue;
                    }

                    if (existingEntityType.Name != entityTypeFromReflection.Name ||
                        existingEntityType.IsEntity != entityTypeFromReflection.IsEntity ||
                        existingEntityType.IsSecured != entityTypeFromReflection.IsSecured ||
                        existingEntityType.FriendlyName != (existingEntityType.FriendlyName ?? entityTypeFromReflection.FriendlyName) ||
                        existingEntityType.AssemblyName != entityTypeFromReflection.AssemblyName)
                    {
                        existingEntityType.Name         = entityTypeFromReflection.Name;
                        existingEntityType.IsEntity     = entityTypeFromReflection.IsEntity;
                        existingEntityType.IsSecured    = entityTypeFromReflection.IsSecured;
                        existingEntityType.FriendlyName = existingEntityType.FriendlyName ?? entityTypeFromReflection.FriendlyName;
                        existingEntityType.AssemblyName = entityTypeFromReflection.AssemblyName;
                    }

                    entityTypesFromReflection.Remove(existingEntityType.Name);
                }

                // Add the newly discovered entities
                foreach (var entityType in entityTypesFromReflection.Values)
                {
                    // Don't add the EntityType entity as it will probably have been automatically
                    // added by the audit on a previous save in this method.
                    if (entityType.Name != "Rock.Model.EntityType")
                    {
                        entityTypeService.Add(entityType);
                    }
                }

                rockContext.SaveChanges();

                // make sure the EntityTypeCache is synced up with any changes that were made
                foreach (var entityTypeModel in entityTypeService.Queryable().AsNoTracking())
                {
                    EntityTypeCache.Get(entityTypeModel);
                }
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Gets a list of ISecured and IEntity entities (all models) that have not yet been registered and adds them
        /// as an <see cref="Rock.Model.EntityType"/>.
        /// </summary>
        /// <param name="physWebAppPath">A <see cref="System.String"/> that represents the physical path of the web application</param>
        public static void RegisterEntityTypes(string physWebAppPath)
        {
            var entityTypes = new Dictionary <string, EntityType>();

            foreach (var type in Rock.Reflection.FindTypes(typeof(Rock.Data.IEntity)))
            {
                var entityType = new EntityType();
                entityType.Name         = type.Key;
                entityType.FriendlyName = type.Value.Name.SplitCase();
                entityType.AssemblyName = type.Value.AssemblyQualifiedName;
                entityType.IsEntity     = !type.Value.GetCustomAttributes(typeof(System.ComponentModel.DataAnnotations.Schema.NotMappedAttribute), false).Any();
                entityType.IsSecured    = false;
                entityTypes.Add(type.Key.ToLower(), entityType);
            }

            foreach (var type in Rock.Reflection.FindTypes(typeof(Rock.Security.ISecured)))
            {
                string key = type.Key.ToLower();

                if (entityTypes.ContainsKey(key))
                {
                    entityTypes[key].IsSecured = true;
                }
                else
                {
                    var entityType = new EntityType();
                    entityType.Name         = type.Key;
                    entityType.FriendlyName = type.Value.Name.SplitCase();
                    entityType.AssemblyName = type.Value.AssemblyQualifiedName;
                    entityType.IsEntity     = false;
                    entityType.IsSecured    = true;
                    entityTypes.Add(key, entityType);
                }
            }

            using (var rockContext = new RockContext())
            {
                var entityTypeService = new EntityTypeService(rockContext);

                // Find any existing EntityTypes marked as an entity or secured that are no longer an entity or secured
                foreach (var oldEntityType in entityTypeService.Queryable()
                         .Where(e => e.IsEntity || e.IsSecured)
                         .ToList())
                {
                    if (!entityTypes.Keys.Contains(oldEntityType.Name.ToLower()))
                    {
                        oldEntityType.IsSecured    = false;
                        oldEntityType.IsEntity     = false;
                        oldEntityType.AssemblyName = null;
                        EntityTypeCache.Flush(oldEntityType.Id);
                    }
                }

                // Update any existing entities
                foreach (var existingEntityType in entityTypeService.Queryable()
                         .Where(e => entityTypes.Keys.Contains(e.Name))
                         .ToList())
                {
                    var key = existingEntityType.Name.ToLower();

                    var entityType = entityTypes[key];

                    if (existingEntityType.Name != entityType.Name ||
                        existingEntityType.IsEntity != entityType.IsEntity ||
                        existingEntityType.IsSecured != entityType.IsSecured ||
                        existingEntityType.FriendlyName != (existingEntityType.FriendlyName ?? entityType.FriendlyName) ||
                        existingEntityType.AssemblyName != entityType.AssemblyName)
                    {
                        existingEntityType.Name         = entityType.Name;
                        existingEntityType.IsEntity     = entityType.IsEntity;
                        existingEntityType.IsSecured    = entityType.IsSecured;
                        existingEntityType.FriendlyName = existingEntityType.FriendlyName ?? entityType.FriendlyName;
                        existingEntityType.AssemblyName = entityType.AssemblyName;
                        EntityTypeCache.Flush(existingEntityType.Id);
                    }
                    entityTypes.Remove(key);
                }

                // Add the newly discovered entities
                foreach (var entityTypeInfo in entityTypes)
                {
                    // Don't add the EntityType entity as it will probably have been automatically
                    // added by the audit on a previous save in this method.
                    if (entityTypeInfo.Value.Name != "Rock.Model.EntityType")
                    {
                        entityTypeService.Add(entityTypeInfo.Value);
                    }
                }

                rockContext.SaveChanges();

                // make sure the EntityTypeCache is synced up with any changes that were made
                foreach (var entityTypeModel in entityTypeService.Queryable())
                {
                    EntityTypeCache.Read(entityTypeModel);
                }
            }
        }