Beispiel #1
0
        /// <summary>
        /// Restore the property information from encodedEntity into the newly created entity.
        /// </summary>
        /// <param name="entity">The blank entity to be populated.</param>
        /// <param name="encodedEntity">The encoded entity data.</param>
        protected void RestoreEntityProperties(IEntity entity, EncodedEntity encodedEntity)
        {
            foreach (var property in GetEntityProperties(entity))
            {
                //
                // If this is a plain property, just set the value.
                //
                if (encodedEntity.Properties.ContainsKey(property.Name))
                {
                    var value = encodedEntity.Properties[property.Name];

                    //
                    // If this is a Guid, see if we need to remap it.
                    //
                    Guid?guidValue = null;
                    if (value is Guid)
                    {
                        guidValue = ( Guid )value;
                        value     = FindMappedGuid(guidValue.Value);
                    }
                    else if (value is string)
                    {
                        guidValue = (( string )value).AsGuidOrNull();
                        if (guidValue.HasValue && guidValue.Value != FindMappedGuid(guidValue.Value))
                        {
                            value = FindMappedGuid(guidValue.Value).ToString();
                        }
                    }

                    property.SetValue(entity, ChangeType(property.PropertyType, value));
                }
            }

            //
            // Restore all references.
            //
            foreach (var reference in encodedEntity.References)
            {
                reference.Restore(entity, this);
            }
        }
Beispiel #2
0
        /// <summary>
        /// Creates a new entity in the database from the encoded information. The entity
        /// is saved before being returned.
        /// </summary>
        /// <param name="encodedEntity">The encoded entity information to create the new entity from.</param>
        /// <returns>A reference to the new entity.</returns>
        protected IEntity CreateNewEntity(EncodedEntity encodedEntity)
        {
            Type entityType = Reflection.FindType(typeof(IEntity), encodedEntity.EntityType);
            var  service    = Reflection.GetServiceForEntityType(entityType, RockContext);

            if (service != null)
            {
                var addMethod = service.GetType().GetMethod("Add", new Type[] { entityType });

                if (addMethod != null)
                {
                    IEntity entity = ( IEntity )Activator.CreateInstance(entityType);

                    RestoreEntityProperties(entity, encodedEntity);
                    entity.Guid = FindMappedGuid(encodedEntity.Guid);

                    //
                    // Do custom pre-save processing.
                    //
                    foreach (var processor in FindEntityProcessors(entityType))
                    {
                        processor.ProcessImportedEntity(entity, encodedEntity, encodedEntity.GetTransformData(processor.Identifier.ToString()), this);
                    }

                    //
                    // Special handling of AttributeQualifier because Guids may not be the same
                    // across installations and the AttributeId+Key columns make up a unique key.
                    //
                    if (encodedEntity.EntityType == "Rock.Model.AttributeQualifier")
                    {
                        var    reference = encodedEntity.References.Where(r => r.Property == "AttributeId").First();
                        var    attribute = GetExistingEntity("Rock.Model.Attribute", FindMappedGuid(new Guid(( string )reference.Data)));
                        string key       = ( string )encodedEntity.Properties["Key"];

                        var existingEntity = new AttributeQualifierService(RockContext)
                                             .GetByAttributeId(attribute.Id)
                                             .Where(a => a.Key == key)
                                             .FirstOrDefault();

                        if (existingEntity != null)
                        {
                            if (entity.Guid != encodedEntity.Guid)
                            {
                                throw new Exception("AttributeQualifier marked for new Guid but conflicting value already exists.");
                            }

                            GuidMap.AddOrReplace(encodedEntity.Guid, existingEntity.Guid);

                            return(existingEntity);
                        }
                    }

                    //
                    // Special handling of Attribute's. The guid's might be different but if the entity type,
                    // entity qualifiers and key are the same, assume it's the same.
                    //
                    else if (encodedEntity.EntityType == "Rock.Model.Attribute")
                    {
                        var attribute      = (Rock.Model.Attribute)entity;
                        var existingEntity = new AttributeService(RockContext)
                                             .GetByEntityTypeId(attribute.EntityTypeId)
                                             .Where(a => a.EntityTypeQualifierColumn == attribute.EntityTypeQualifierColumn && a.EntityTypeQualifierValue == attribute.EntityTypeQualifierValue && a.Key == attribute.Key)
                                             .FirstOrDefault();

                        if (existingEntity != null)
                        {
                            if (entity.Guid != encodedEntity.Guid)
                            {
                                throw new Exception("Attribute marked for new Guid but conflicting value already exists.");
                            }

                            GuidMap.AddOrReplace(encodedEntity.Guid, existingEntity.Guid);

                            return(existingEntity);
                        }
                    }

                    //
                    // Special handling of AttributeValue's. The guid's might be different but if the attribute Id
                    // and entity Id are the same, assume it's the same.
                    //
                    else if (encodedEntity.EntityType == "Rock.Model.AttributeValue")
                    {
                        var attributeReference = encodedEntity.References.Where(r => r.Property == "AttributeId").First();
                        var attribute          = GetExistingEntity("Rock.Model.Attribute", FindMappedGuid(new Guid(( string )attributeReference.Data)));
                        var entityReference    = encodedEntity.References.Where(r => r.Property == "EntityId").First();
                        var entityRef          = GetExistingEntity(entityReference.EntityType, FindMappedGuid(new Guid(( string )entityReference.Data)));

                        var existingEntity = new AttributeValueService(RockContext)
                                             .Queryable().Where(a => a.AttributeId == attribute.Id && a.EntityId == entityRef.Id)
                                             .FirstOrDefault();

                        if (existingEntity != null)
                        {
                            if (entity.Guid != encodedEntity.Guid)
                            {
                                throw new Exception("AttributeValue marked for new Guid but conflicting value already exists.");
                            }

                            GuidMap.AddOrReplace(encodedEntity.Guid, existingEntity.Guid);

                            return(existingEntity);
                        }
                    }

                    addMethod.Invoke(service, new object[] { entity });
                    RockContext.SaveChanges(true);

                    return(entity);
                }
            }

            throw new Exception(string.Format("Failed to create new database entity for {0}_{1}", encodedEntity.EntityType, encodedEntity.Guid));
        }
        /// <summary>
        /// Export the given entity into an EncodedEntity object. This can be used later to
        /// reconstruct the entity.
        /// </summary>
        /// <param name="entity">The entity to be exported.</param>
        /// <returns>The exported data that can be imported.</returns>
        protected EncodedEntity Export(QueuedEntity queuedEntity)
        {
            EncodedEntity encodedEntity = new EncodedEntity();
            Type          entityType    = GetEntityType(queuedEntity.Entity);

            encodedEntity.Guid       = queuedEntity.Entity.Guid;
            encodedEntity.EntityType = entityType.FullName;

            //
            // Generate the standard properties and references.
            //
            foreach (var property in GetEntityProperties(queuedEntity.Entity))
            {
                //
                // Don't encode IEntity properties, we should have the Id encoded instead.
                //
                if (typeof(IEntity).IsAssignableFrom(property.PropertyType))
                {
                    continue;
                }

                //
                // Don't encode IEnumerable properties. Those should be included as
                // their own entities to be encoded later.
                //
                if (property.PropertyType.GetInterface("IEnumerable") != null &&
                    property.PropertyType.GetGenericArguments().Length == 1 &&
                    typeof(IEntity).IsAssignableFrom(property.PropertyType.GetGenericArguments()[0]))
                {
                    continue;
                }

                encodedEntity.Properties.Add(property.Name, property.GetValue(queuedEntity.Entity));
            }

            //
            // Run any post-process transforms.
            //
            foreach (var processor in FindEntityProcessors(entityType))
            {
                var data = processor.ProcessExportedEntity(queuedEntity.Entity, encodedEntity, this);

                if (data != null)
                {
                    encodedEntity.AddTransformData(processor.Identifier.ToString(), data);
                }
            }

            //
            // Generate the references to other entities.
            //
            foreach (var x in queuedEntity.ReferencedEntities)
            {
                encodedEntity.MakePropertyIntoReference(x.Key, x.Value);
            }

            //
            // Add in the user references.
            //
            encodedEntity.References.AddRange(queuedEntity.UserReferences.Values);

            return(encodedEntity);
        }
Beispiel #4
0
 /// <summary>
 /// An entity has been exported and can now have any post-processing done to it
 /// that is needed. For example a processor might remove some properties that shouldn't
 /// actually have been exported.
 /// </summary>
 /// <param name="entity">The source entity that was exported.</param>
 /// <param name="encodedEntity">The exported data from the entity.</param>
 /// <param name="helper">The helper that is doing the exporting.</param>
 /// <returns>An object that will be encoded with the entity and passed to the ProcessImportEntity method later, or null.</returns>
 public object ProcessExportedEntity(IEntity entity, EncodedEntity encodedEntity, EntityCoder helper)
 {
     return(ProcessExportedEntity(( T )entity, encodedEntity, helper));
 }
Beispiel #5
0
 /// <summary>
 /// This method is called before the entity is saved and allows any final changes to the
 /// entity before it is stored in the database. Any Guid references that are not standard
 /// properties must also be updated, such as the Actions string of a WorkflowActionForm.
 /// </summary>
 /// <param name="entity">The in-memory entity that is about to be saved.</param>
 /// <param name="encodedEntity">The encoded information that was used to reconstruct the entity.</param>
 /// <param name="data">Custom data that was previously returned by ProcessExportedEntity.</param>
 /// <param name="helper">The helper in charge of the import process.</param>
 protected virtual void ProcessImportedEntity(T entity, EncodedEntity encodedEntity, object data, EntityDecoder helper)
 {
 }
Beispiel #6
0
 /// <summary>
 /// This method is called before the entity is saved and allows any final changes to the
 /// entity before it is stored in the database. Any Guid references that are not standard
 /// properties must also be updated, such as the Actions string of a WorkflowActionForm.
 /// </summary>
 /// <param name="entity">The in-memory entity that is about to be saved.</param>
 /// <param name="encodedEntity">The encoded information that was used to reconstruct the entity.</param>
 /// <param name="data">Custom data that was previously returned by ProcessExportedEntity.</param>
 /// <param name="helper">The helper in charge of the import process.</param>
 public void ProcessImportedEntity(IEntity entity, EncodedEntity encodedEntity, object data, EntityDecoder helper)
 {
     ProcessImportedEntity(( T )entity, encodedEntity, data, helper);
 }
Beispiel #7
0
 /// <summary>
 /// An entity has been exported and can now have any post-processing done to it
 /// that is needed. For example a processor might remove some properties that shouldn't
 /// actually have been exported.
 /// </summary>
 /// <param name="entity">The source entity that was exported.</param>
 /// <param name="encodedEntity">The exported data from the entity.</param>
 /// <param name="helper">The helper that is doing the exporting.</param>
 /// <returns>An object that will be encoded with the entity and passed to the ProcessImportEntity method later, or null.</returns>
 protected virtual object ProcessExportedEntity(T entity, EncodedEntity encodedEntity, EntityCoder helper)
 {
     return(null);
 }