//@SuppressWarnings({"unchecked"})
        public void AddComponent(XmlElement parent, PropertyAuditingData propertyAuditingData,
                                 IValue value, ICompositeMapperBuilder mapper, String entityName,
                                 EntityXmlMappingData xmlMappingData, bool firstPass)
        {
            Component prop_component = (Component)value;

            ICompositeMapperBuilder componentMapper = mapper.AddComponent(propertyAuditingData.getPropertyData(),
                                                                          prop_component.ComponentClassName);

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

            // Adding all properties of the component
            IEnumerator <Property> properties = (IEnumerator <Property>)prop_component.PropertyIterator.GetEnumerator();

            while (properties.MoveNext())
            {
                Property property = properties.Current;

                PropertyAuditingData 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, firstPass);
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Add value to middle table
        /// </summary>
        /// <param name="value">Value, which should be mapped to the middle-table, either as a relation to another entity, or as a simple value.</param>
        /// <param name="xmlMapping">If not <code>null</code>, xml mapping for this value is added to this element.</param>
        /// <param name="queryGeneratorBuilder">In case <code>value</code> is a relation to another entity, information about it should be added to the given.</param>
        /// <param name="prefix">Prefix for proeprty names of related entities identifiers.</param>
        /// <param name="joinColumns">Names of columns to use in the xml mapping, if this array isn't null and has any elements.</param>
        /// <returns>Data for mapping this component.</returns>
        private MiddleComponentData addValueToMiddleTable(IValue value, XElement xmlMapping,
                                                          QueryGeneratorBuilder queryGeneratorBuilder,
                                                          string prefix, string[] joinColumns)
        {
            var type = value.Type;

            if (type is ManyToOneType)
            {
                var prefixRelated        = prefix + "_";
                var referencedEntityName = MappingTools.ReferencedEntityName(value);

                var referencedIdMapping = _mainGenerator.GetReferencedIdMappingData(_referencingEntityName,
                                                                                    referencedEntityName, _propertyAuditingData, true);

                // Adding related-entity (in this case: the referenced entities id) id mapping to the xml only if the
                // relation isn't inverse (so when <code>xmlMapping</code> is not null).
                if (xmlMapping != null)
                {
                    addRelatedToXmlMapping(xmlMapping, prefixRelated,
                                           joinColumns != null && joinColumns.Length > 0
                                                                        ? joinColumns
                                                                        : MetadataTools.GetColumnNameEnumerator(value.ColumnIterator),
                                           referencedIdMapping);
                }

                // Storing the id data of the referenced entity: original mapper, prefixed mapper and entity name.
                var referencedIdData = createMiddleIdData(referencedIdMapping,
                                                          prefixRelated, referencedEntityName);
                // And adding it to the generator builder.
                queryGeneratorBuilder.AddRelation(referencedIdData);

                return(new MiddleComponentData(new MiddleRelatedComponentMapper(referencedIdData),
                                               queryGeneratorBuilder.CurrentIndex));
            }
            else if (type is ComponentType)
            {
                //collection of embaddable elements
                var component        = (Component)value;
                var componentMapper  = new MiddleEmbeddableComponentMapper(new MultiPropertyMapper(), component.ComponentClassName);
                var parentXmlMapping = xmlMapping.Parent;

                var auditData = new ComponentAuditingData();

                new ComponentAuditedPropertiesReader(_metaDataStore,
                                                     new AuditedPropertiesReader.ComponentPropertiesSource(component),
                                                     auditData, _mainGenerator.GlobalCfg, "").Read();

                // Emulating first pass.
                foreach (var auditedPropertyName in auditData.PropertyNames)
                {
                    var nestedAuditingData = auditData.GetPropertyAuditingData(auditedPropertyName);
                    _mainGenerator.AddValue(parentXmlMapping, component.GetProperty(auditedPropertyName).Value, componentMapper, prefix, _xmlMappingData, nestedAuditingData, true, true, true);
                }

                // Emulating second pass so that the relations can be mapped too.
                foreach (var auditedPropertyName in auditData.PropertyNames)
                {
                    var nestedAuditingData = auditData.GetPropertyAuditingData(auditedPropertyName);
                    _mainGenerator.AddValue(parentXmlMapping, component.GetProperty(auditedPropertyName).Value, componentMapper, _referencingEntityName, _xmlMappingData, nestedAuditingData, true, false, true);
                }

                // Add an additional column holding a number to make each entry unique within the set.
                // Embeddable properties may contain null values, so cannot be stored within composite primary key.
                if (_propertyValue.IsSet)
                {
                    var setOrdinalPropertyName = _mainGenerator.VerEntCfg.EmbeddableSetOrdinalPropertyName;
                    var ordinalProperty        = MetadataTools.AddProperty(xmlMapping, setOrdinalPropertyName, "int", true, true, null);
                    MetadataTools.AddColumn(ordinalProperty, setOrdinalPropertyName, -1, -1, -1, null, false);
                }
                return(new MiddleComponentData(componentMapper, 0));
            }
            // Last but one parameter: collection components are always insertable
            var mapped = _mainGenerator.BasicMetadataGenerator.AddBasic(xmlMapping,
                                                                        new PropertyAuditingData(prefix, "field"),
                                                                        value, null, true, true);

            if (mapped)
            {
                // Simple values are always stored in the first item of the array returned by the query generator.
                return(new MiddleComponentData(new MiddleSimpleComponentMapper(_mainGenerator.VerEntCfg, prefix), 0));
            }
            _mainGenerator.ThrowUnsupportedTypeException(type, _referencingEntityName, _propertyName);
            // Impossible to get here.
            throw new AssertionFailure();
        }