コード例 #1
0
        private static void addCustomValue(XElement parent, PropertyAuditingData propertyAuditingData,
                                           IValue value, ISimpleMapperBuilder mapper, bool insertable,
                                           bool key, System.Type typeOfUserImplementation)
        {
            if (parent != null)
            {
                var propMapping = MetadataTools.AddProperty(parent, propertyAuditingData.Name,
                                                            typeOfUserImplementation.AssemblyQualifiedName, insertable, key);
                MetadataTools.AddColumns(propMapping, value.ColumnIterator.OfType <Column>());
                var typeElement = new XElement(MetadataTools.CreateElementName("type"),
                                               new XAttribute("name", typeOfUserImplementation.AssemblyQualifiedName));

                var simpleValue = value as SimpleValue;
                if (simpleValue != null)
                {
                    var typeParameters = simpleValue.TypeParameters;
                    if (typeParameters != null)
                    {
                        foreach (var paramKeyValue in typeParameters)
                        {
                            var typeParam = new XElement(MetadataTools.CreateElementName("param"),
                                                         new XAttribute("name", paramKeyValue.Key), paramKeyValue.Value);
                            typeElement.Add(typeParam);
                        }
                    }
                }
                propMapping.Add(typeElement);
            }

            if (mapper != null)
            {
                mapper.Add(propertyAuditingData.GetPropertyData());
            }
        }
コード例 #2
0
        public void AddOneToOneNotOwning(PropertyAuditingData propertyAuditingData, IValue value, ICompositeMapperBuilder mapper, string entityName)
        {
            var propertyValue = (OneToOne)value;
            var owningReferencePropertyName = propertyValue.ReferencedPropertyName;             // mappedBy

            var configuration = _mainGenerator.EntitiesConfigurations[entityName];

            if (configuration == null)
            {
                throw new MappingException("An audited relation to a non-audited entity " + entityName + "!");
            }

            var ownedIdMapping = configuration.IdMappingData;

            if (ownedIdMapping == null)
            {
                throw new MappingException("An audited relation to a non-audited entity " + entityName + "!");
            }

            var lastPropertyPrefix   = MappingTools.CreateToOneRelationPrefix(owningReferencePropertyName);
            var referencedEntityName = propertyValue.ReferencedEntityName;

            // Generating the id mapper for the relation
            var ownedIdMapper = ownedIdMapping.IdMapper.PrefixMappedProperties(lastPropertyPrefix);

            // Storing information about this relation
            _mainGenerator.EntitiesConfigurations[entityName].AddToOneNotOwningRelation(
                propertyAuditingData.Name, owningReferencePropertyName,
                referencedEntityName, ownedIdMapper, MappingTools.IgnoreNotFound(value));

            // Adding mapper for the id
            var propertyData = propertyAuditingData.GetPropertyData();

            mapper.AddComposite(propertyData, new OneToOneNotOwningMapper(entityName, referencedEntityName, owningReferencePropertyName, propertyData));
        }
コード例 #3
0
        public void AddComponent(XElement parent, PropertyAuditingData propertyAuditingData,
                                 IValue value, ICompositeMapperBuilder mapper, string entityName,
                                 EntityXmlMappingData xmlMappingData, bool firstPass, bool insertable)
        {
            var propComponent = (Component)value;

            var componentMapper = mapper.AddComponent(propertyAuditingData.GetPropertyData(),
                                                      propComponent.ComponentClassName);

            // The property auditing data must be for a component.
            var componentAuditingData = (ComponentAuditingData)propertyAuditingData;

            // Adding all properties of the component
            foreach (var property in propComponent.PropertyIterator)
            {
                var componentPropertyAuditingData = componentAuditingData.GetPropertyAuditingData(property.Name);

                // Checking if that property is audited
                if (componentPropertyAuditingData != null)
                {
                    mainGenerator.AddValue(parent, property.Value, componentMapper, entityName, xmlMappingData,
                                           componentPropertyAuditingData, property.IsInsertable && insertable, firstPass, false);
                }
            }
        }
コード例 #4
0
        public void AddKeyManyToOne(XElement parent, PropertyAuditingData propertyAuditingData, IValue value, ISimpleMapperBuilder mapper)
        {
            var type    = value.Type;
            var element = mapper == null?
                          MetadataTools.AddKeyManyToOne(parent, propertyAuditingData.Name, type.ReturnedClass.AssemblyQualifiedName) :
                              MetadataTools.AddManyToOne(parent, propertyAuditingData.Name, type.ReturnedClass.AssemblyQualifiedName, true, false);

            MetadataTools.AddColumns(element, value.ColumnIterator.OfType <Column>());
            mapper?.Add(propertyAuditingData.GetPropertyData());
        }
コード例 #5
0
        private static void addSimpleValue(XElement parent, PropertyAuditingData propertyAuditingData,
                                           IValue value, ISimpleMapperBuilder mapper, bool insertable, bool key)
        {
            if (parent != null)
            {
                var propMapping = MetadataTools.AddProperty(parent, propertyAuditingData.Name,
                                                            value.Type.Name, propertyAuditingData.ForceInsertable || insertable, key, propertyAuditingData.AccessType);
                MetadataTools.AddColumns(propMapping, value.ColumnIterator.OfType <Column>());
            }

            // A null mapper means that we only want to add xml mappings
            mapper?.Add(propertyAuditingData.GetPropertyData());
        }
コード例 #6
0
        public void AddOneToOnePrimaryKeyJoinColumn(PropertyAuditingData propertyAuditingData, IValue value, ICompositeMapperBuilder mapper, string entityName, bool insertable)
        {
            var referencedEntityName = ((ToOne)value).ReferencedEntityName;
            var idMapping            = _mainGenerator.GetReferencedIdMappingData(entityName, referencedEntityName, propertyAuditingData, true);
            var lastPropertyPrefix   = MappingTools.CreateToOneRelationPrefix(propertyAuditingData.Name);

            // Generating the id mapper for the relation
            var relMapper = idMapping.IdMapper.PrefixMappedProperties(lastPropertyPrefix);

            // Storing information about this relation
            _mainGenerator.EntitiesConfigurations[entityName].AddToOneRelation(propertyAuditingData.Name, referencedEntityName, relMapper, insertable, MappingTools.IgnoreNotFound(value));

            // Adding mapper for the id
            var propertyData = propertyAuditingData.GetPropertyData();

            mapper.AddComposite(propertyData, new OneToOnePrimaryKeyJoinColumnMapper(entityName, referencedEntityName, propertyData));
        }
コード例 #7
0
        private void addOneToManyAttached(bool fakeOneToManyBidirectional)
        {
            log.Debug("Adding audit mapping for property {0}. {1}" +
                      ": one-to-many collection, using a join column on the referenced entity.", _referencingEntityName, _propertyName);

            var mappedBy = getMappedBy(_propertyValue);

            var referencedIdMapping = _mainGenerator.GetReferencedIdMappingData(_referencingEntityName,
                                                                                _referencedEntityName, _propertyAuditingData, false);
            var referencingIdMapping = _referencingEntityConfiguration.IdMappingData;

            // Generating the id mappers data for the referencing side of the relation.
            var referencingIdData = createMiddleIdData(referencingIdMapping,
                                                       mappedBy + "_", _referencingEntityName);

            // And for the referenced side. The prefixed mapper won't be used (as this collection isn't persisted
            // in a join table, so the prefix value is arbitrary).
            var referencedIdData = createMiddleIdData(referencedIdMapping,
                                                      null, _referencedEntityName);

            // Generating the element mapping.
            var elementComponentData = new MiddleComponentData(
                new MiddleRelatedComponentMapper(referencedIdData), 0);

            // Generating the index mapping, if an index exists. It can only exists in case a javax.persistence.MapKey
            // annotation is present on the entity. So the middleEntityXml will be not be used. The queryGeneratorBuilder
            // will only be checked for nullnes.
            var indexComponentData = addIndex(null, null);

            // Generating the query generator - it should read directly from the related entity.
            var queryGenerator = new OneAuditEntityQueryGenerator(_mainGenerator.VerEntCfg,
                                                                  _mainGenerator.GlobalCfg.AuditStrategy, referencingIdData, _referencedEntityName, referencedIdData, isEmbeddableElementType());

            // Creating common mapper data.
            var commonCollectionMapperData = new CommonCollectionMapperData(
                _mainGenerator.VerEntCfg, _referencedEntityName,
                _propertyAuditingData.GetPropertyData(),
                referencingIdData, queryGenerator);

            IPropertyMapper fakeBidirectionalRelationMapper;
            IPropertyMapper fakeBidirectionalRelationIndexMapper;

            if (fakeOneToManyBidirectional)
            {
                // In case of a fake many-to-one bidirectional relation, we have to generate a mapper which maps
                // the mapped-by property name to the id of the related entity (which is the owner of the collection).
                var auditMappedBy = _propertyAuditingData.MappedBy;

                // Creating a prefixed relation mapper.
                var relMapper = referencingIdMapping.IdMapper.PrefixMappedProperties(
                    MappingTools.CreateToOneRelationPrefix(auditMappedBy));

                fakeBidirectionalRelationMapper = new ToOneIdMapper(
                    _mainGenerator.GlobalCfg.EnversProxyFactory,
                    relMapper,
                    // The mapper will only be used to map from entity to map, so no need to provide other details
                    // when constructing the PropertyData.
                    new PropertyData(auditMappedBy, null, null),
                    _referencedEntityName, false);

                // Checking if there's an index defined. If so, adding a mapper for it.
                if (_propertyAuditingData.PositionMappedBy != null)
                {
                    var positionMappedBy = _propertyAuditingData.PositionMappedBy;
                    fakeBidirectionalRelationIndexMapper = new SinglePropertyMapper(new PropertyData(positionMappedBy, null, null));

                    // Also, overwriting the index component data to properly read the index.
                    indexComponentData = new MiddleComponentData(new MiddleStraightComponentMapper(positionMappedBy), 0);
                }
                else
                {
                    fakeBidirectionalRelationIndexMapper = null;
                }
            }
            else
            {
                fakeBidirectionalRelationMapper      = null;
                fakeBidirectionalRelationIndexMapper = null;
            }

            // Checking the type of the collection and adding an appropriate mapper.
            addMapper(commonCollectionMapperData, elementComponentData, indexComponentData);

            // Storing information about this relation.
            _referencingEntityConfiguration.AddToManyNotOwningRelation(_propertyName, mappedBy,
                                                                       _referencedEntityName, referencingIdData.PrefixedMapper, fakeBidirectionalRelationMapper,
                                                                       fakeBidirectionalRelationIndexMapper);
        }
コード例 #8
0
        public void AddToOne(XElement parent, PropertyAuditingData propertyAuditingData, IValue value,
                             ICompositeMapperBuilder mapper, string entityName, bool insertable)
        {
            var referencedEntityName = ((ToOne)value).ReferencedEntityName;
            var idMapping            = _mainGenerator.GetReferencedIdMappingData(entityName, referencedEntityName,
                                                                                 propertyAuditingData, true);

            var lastPropertyPrefix = MappingTools.CreateToOneRelationPrefix(propertyAuditingData.Name);

            // Generating the id mapper for the relation
            var relMapper = idMapping.IdMapper.PrefixMappedProperties(lastPropertyPrefix);

            // Storing information about this relation
            _mainGenerator.EntitiesConfigurations[entityName].AddToOneRelation(
                propertyAuditingData.Name, referencedEntityName, relMapper, insertable, MappingTools.IgnoreNotFound(value));

            // If the property isn't insertable, checking if this is not a "fake" bidirectional many-to-one relationship,
            // that is, when the one side owns the relation (and is a collection), and the many side is non insertable.
            // When that's the case and the user specified to store this relation without a middle table (using
            // @AuditMappedBy), we have to make the property insertable for the purposes of Envers. In case of changes to
            // the entity that didn't involve the relation, it's value will then be stored properly. In case of changes
            // to the entity that did involve the relation, it's the responsibility of the collection side to store the
            // proper data.
            bool nonInsertableFake;

            if (!insertable && propertyAuditingData.ForceInsertable)
            {
                nonInsertableFake = true;
                insertable        = true;
            }
            else
            {
                nonInsertableFake = false;
            }


            // Adding an element to the mapping corresponding to the references entity id's
            var properties = new XElement(idMapping.XmlRelationMapping);

            properties.Add(new XAttribute("name", propertyAuditingData.Name));

            MetadataTools.PrefixNamesInPropertyElement(properties, lastPropertyPrefix,
                                                       MetadataTools.GetColumnNameEnumerator(value.ColumnIterator),
                                                       false, insertable, propertyAuditingData.AccessType);

            // Extracting related id properties from properties tag
            var firstJoin = firstJoinElement(parent);

            foreach (var element in properties.Elements())
            {
                if (firstJoin == null)
                {
                    parent.Add(element);
                }
                else
                {
                    firstJoin.AddBeforeSelf(element);
                }
            }

            // Adding mapper for the id
            var propertyData = propertyAuditingData.GetPropertyData();

            mapper.AddComposite(propertyData, new ToOneIdMapper(relMapper, propertyData, referencedEntityName, nonInsertableFake));
        }