Search in sources :

Example 1 with AbstractAttribute

use of com.blazebit.persistence.view.impl.metamodel.AbstractAttribute in project blaze-persistence by Blazebit.

the class ViewMapper method createAccessor.

private ObjectMapper createAccessor(ManagedViewType<S> sourceType, ManagedViewType<T> targetType, boolean ignoreMissing, EntityViewKindMapping entityViewKindMapping, EntityViewManager entityViewManager, ProxyFactory proxyFactory, MethodAttribute<? super T, ?> targetAttribute, String prefix, Map<String, Key<Object, Object>> subMappers) {
    String newPrefix;
    if (prefix.isEmpty()) {
        newPrefix = targetAttribute.getName();
    } else {
        newPrefix = prefix + "." + targetAttribute.getName();
    }
    Type<?> attributeType;
    MappingConstructorImpl<?> constructor = null;
    Boolean maybeMarkNew = entityViewKindMapping == EntityViewKindMapping.MARK_NEW ? null : false;
    Key<Object, Object> subMapperKey = subMappers.get(newPrefix);
    if (subMapperKey == Key.EXCLUDE_MARKER) {
        return null;
    } else if (subMapperKey != null) {
        ignoreMissing = subMapperKey.ignoreMissing;
        maybeMarkNew = subMapperKey.markNew;
    }
    // Try to find a source attribute
    MethodAttribute<?, ?> sourceAttribute;
    AttributeAccessor accessor;
    if (sourceType == null) {
        sourceAttribute = null;
        if (targetAttribute.getMappingType() == Attribute.MappingType.PARAMETER) {
            return new ParameterObjectMapper(((MappingAttribute<?, ?>) targetAttribute).getMapping());
        }
        accessor = Accessors.forEntityMapping((EntityViewManagerImpl) entityViewManager, targetAttribute);
        if (accessor == null) {
            if (ignoreMissing) {
                return null;
            }
            throw inconvertible("Attribute '" + targetAttribute.getName() + "' from target type is missing in source type!", targetType);
        }
    } else {
        sourceAttribute = sourceType.getAttribute(targetAttribute.getName());
        if (sourceAttribute == null) {
            if (targetAttribute.getMappingType() == Attribute.MappingType.PARAMETER) {
                return new ParameterObjectMapper(((MappingAttribute<?, ?>) targetAttribute).getMapping());
            }
            // Optionally ignore missing attributes
            if (ignoreMissing) {
                return null;
            }
            throw inconvertible("Attribute '" + targetAttribute.getName() + "' from target type is missing in source type!", sourceType, targetType);
        }
        accessor = Accessors.forViewAttribute(null, sourceAttribute, true);
    }
    // Handle conversion from one type to another
    if (targetAttribute.isCollection()) {
        if ((sourceAttribute != null) && (targetAttribute.getConvertedJavaType() != sourceAttribute.getConvertedJavaType())) {
            throw inconvertible("Attribute '" + targetAttribute.getName() + "' from target type has a different plural type than in source type!", sourceType, targetType);
        }
        PluralAttribute<?, ?, ?> targetPluralAttr = (PluralAttribute<?, ?, ?>) targetAttribute;
        Type<?> elementType = (sourceAttribute == null) ? null : ((PluralAttribute<?, ?, ?>) sourceAttribute).getElementType();
        ViewMapper<Object, Object> valueMapper = null;
        attributeType = targetPluralAttr.getElementType();
        if (subMapperKey != null) {
            attributeType = subMapperKey.targetType;
            constructor = subMapperKey.targetConstructor;
        }
        if (targetAttribute.isSubview()) {
            valueMapper = createViewMapper(elementType, attributeType, constructor, ignoreMissing, maybeMarkNew, entityViewManager, proxyFactory, newPrefix, subMappers);
        } else if ((sourceType != null) && (targetPluralAttr.getElementType() != elementType)) {
            throw inconvertible("Attribute '" + targetAttribute.getName() + "' from target type has a different element type than in source type!", sourceType, targetType);
        }
        boolean needsDirtyTracker = ((AbstractAttribute<?, ?>) targetAttribute).needsDirtyTracker();
        if (targetPluralAttr.getCollectionType() == PluralAttribute.CollectionType.MAP) {
            MapAttribute<?, ?, ?> targetMapAttr = (MapAttribute<?, ?, ?>) targetAttribute;
            Type<?> keyType = (sourceAttribute == null) ? null : ((MapAttribute<?, ?, ?>) sourceAttribute).getKeyType();
            ViewMapper<Object, Object> keyMapper = null;
            if (targetMapAttr.isKeySubview()) {
                String newKeyPrefix = "KEY(" + newPrefix + ")";
                Key<Object, Object> keySubMapperKey = subMappers.get(newKeyPrefix);
                if (keySubMapperKey == Key.EXCLUDE_MARKER) {
                    keyMapper = null;
                } else {
                    constructor = null;
                    Type<?> keyTargetType = targetMapAttr.getKeyType();
                    Boolean maybeMarkNewKey = entityViewKindMapping == EntityViewKindMapping.MARK_NEW ? null : false;
                    if (subMapperKey != null) {
                        constructor = keySubMapperKey.targetConstructor;
                        keyTargetType = keySubMapperKey.targetType;
                        ignoreMissing = keySubMapperKey.ignoreMissing;
                        maybeMarkNewKey = keySubMapperKey.markNew;
                    }
                    keyMapper = createViewMapper(keyType, keyTargetType, constructor, ignoreMissing, maybeMarkNewKey, entityViewManager, proxyFactory, newPrefix, subMappers);
                }
            } else if ((sourceType != null) && (targetMapAttr.getKeyType() != keyType)) {
                throw inconvertible("Attribute '" + targetAttribute.getName() + "' from target type has a different key type than in source type!", sourceType, targetType);
            }
            MapInstantiatorImplementor<?, ?> mapInstantiator = ((AbstractAttribute<?, ?>) targetAttribute).getMapInstantiator();
            return new MapObjectMapper(accessor, needsDirtyTracker, entityViewKindMapping != EntityViewKindMapping.MARK_NEW, mapInstantiator, keyMapper, valueMapper);
        } else {
            CollectionInstantiatorImplementor<?, ?> collectionInstantiator = ((AbstractAttribute<?, ?>) targetAttribute).getCollectionInstantiator();
            return new CollectionObjectMapper(accessor, needsDirtyTracker, entityViewKindMapping != EntityViewKindMapping.MARK_NEW, collectionInstantiator, valueMapper);
        }
    } else if (targetAttribute.isSubview()) {
        attributeType = ((SingularAttribute<?, ?>) targetAttribute).getType();
        if (subMapperKey != null) {
            attributeType = subMapperKey.targetType;
            constructor = subMapperKey.targetConstructor;
        }
        Type<?> type = (sourceAttribute == null) ? null : ((SingularAttribute<?, ?>) sourceAttribute).getType();
        ViewMapper<Object, Object> mapper = createViewMapper(type, attributeType, constructor, ignoreMissing, maybeMarkNew, entityViewManager, proxyFactory, newPrefix, subMappers);
        return new AttributeObjectMapper(accessor, mapper);
    } else if ((sourceAttribute != null) && (targetAttribute.getConvertedJavaType() != sourceAttribute.getConvertedJavaType())) {
        throw inconvertible("Attribute '" + targetAttribute.getName() + "' from target type has a different type than in source type!", sourceType, targetType);
    } else {
        return new PassthroughObjectMapper(accessor);
    }
}
Also used : AbstractAttribute(com.blazebit.persistence.view.impl.metamodel.AbstractAttribute) EntityViewManagerImpl(com.blazebit.persistence.view.impl.EntityViewManagerImpl) PluralAttribute(com.blazebit.persistence.view.metamodel.PluralAttribute) MapAttribute(com.blazebit.persistence.view.metamodel.MapAttribute) SingularAttribute(com.blazebit.persistence.view.metamodel.SingularAttribute) Type(com.blazebit.persistence.view.metamodel.Type) ManagedViewType(com.blazebit.persistence.view.metamodel.ManagedViewType) ViewType(com.blazebit.persistence.view.metamodel.ViewType) AttributeAccessor(com.blazebit.persistence.view.impl.accessor.AttributeAccessor)

Example 2 with AbstractAttribute

use of com.blazebit.persistence.view.impl.metamodel.AbstractAttribute in project blaze-persistence by Blazebit.

the class ViewTypeObjectBuilderTemplate method applySubviewMapping.

@SuppressWarnings("unchecked")
private ViewTypeObjectBuilderTemplate<Object[]>[] applySubviewMapping(MappingAttribute<? super T, ?> mappingAttribute, String subviewAttributePath, TupleIdDescriptor tupleIdDescriptor, ManagedViewTypeImplementor<Object[]> managedViewType, TupleElementMapperBuilder mapperBuilder, ViewJpqlMacro viewJpqlMacro, EmbeddingViewJpqlMacro embeddingViewJpqlMacro, ExpressionFactory ef, boolean isKey, boolean nullIfEmpty) {
    AbstractAttribute<?, ?> attribute = (AbstractAttribute<?, ?>) mappingAttribute;
    String subviewAliasPrefix = mapperBuilder.getAlias(mappingAttribute, isKey);
    String subviewMappingPrefix;
    String subviewIdPrefix;
    int startIndex;
    if (mappingAttribute.getFetchStrategy() == FetchStrategy.MULTISET) {
        startIndex = 0;
    } else {
        startIndex = tupleOffset + mapperBuilder.mapperIndex();
    }
    boolean updatableObjectCache = managedViewType.isUpdatable() || managedViewType.isCreatable();
    TupleIdDescriptor subviewTupleIdDescriptor = new TupleIdDescriptor(tupleIdDescriptor);
    TupleIdDescriptor subviewIdDescriptor;
    String multisetCorrelationExpression;
    if (mappingAttribute.getFetchStrategy() != FetchStrategy.MULTISET) {
        if (isKey) {
            subviewMappingPrefix = mapperBuilder.getKeyMapping((MapAttribute<?, ?, ?>) mappingAttribute);
        } else {
            subviewMappingPrefix = mapperBuilder.getMapping(mappingAttribute);
        }
        subviewIdPrefix = subviewMappingPrefix;
        multisetCorrelationExpression = null;
    } else {
        // Must be in sync with com.blazebit.persistence.view.impl.objectbuilder.mapper.MultisetTupleElementMapper.applyMapping
        subviewMappingPrefix = getMultisetResultAlias(subviewAttributePath);
        subviewIdPrefix = subviewMappingPrefix;
        multisetCorrelationExpression = mapperBuilder.getMapping(mappingAttribute);
    }
    String oldViewPath = viewJpqlMacro.getViewPath();
    viewJpqlMacro.setViewPath(subviewMappingPrefix);
    if (managedViewType instanceof ViewType<?>) {
        // When the attribute is not update mappable i.e. joining over other associations, we use its parent's parent id
        if (attribute.isUpdateMappable()) {
            subviewIdDescriptor = new TupleIdDescriptor();
        } else {
            subviewIdDescriptor = new TupleIdDescriptor(tupleIdDescriptor);
        }
    } else {
        subviewIdDescriptor = new TupleIdDescriptor(tupleIdDescriptor);
        subviewIdDescriptor.addIdPosition(flatViewIdPosition(mappingAttribute));
        subviewTupleIdDescriptor.addIdPosition(flatViewIdPosition(mappingAttribute));
    }
    int endTupleElementsToAdd = 0;
    String indexExpression = null;
    ViewTypeObjectBuilderTemplate<Object[]> indexTemplate = null;
    if (mappingAttribute.getFetchStrategy() == FetchStrategy.MULTISET) {
        if (attribute.getKeyMappingExpression() != null) {
            MapAttribute<?, ?, ?> mapAttribute = (MapAttribute<?, ?, ?>) attribute;
            indexExpression = mapperBuilder.getKeyMapping(subviewMappingPrefix, mapAttribute);
            if (mapAttribute.isKeySubview()) {
                indexTemplate = new ViewTypeObjectBuilderTemplate<Object[]>(viewRoot, viewRootAlias, subviewAttributePath, subviewAliasPrefix, indexExpression, indexExpression, subviewTupleIdDescriptor, subviewIdDescriptor, 1, 0, viewJpqlMacro, embeddingViewJpqlMacro, (Map<ManagedViewType<? extends Object[]>, String>) (Map<?, ?>) mapAttribute.getKeyInheritanceSubtypeMappings(), evm, ef, (ManagedViewTypeImplementor<Object[]>) mapAttribute.getKeyType(), null, proxyFactory);
            }
        } else if (attribute.getMappingIndexExpression() != null) {
            indexExpression = mapperBuilder.getIndexMapping(subviewMappingPrefix, (ListAttribute<?, ?>) attribute);
        }
        if (updatableObjectCache && managedViewType.getMappingType() == Type.MappingType.FLAT_VIEW) {
            if (indexExpression != null) {
                endTupleElementsToAdd = 1;
            } else if (indexTemplate != null) {
                endTupleElementsToAdd = indexTemplate.effectiveTupleSize;
            }
        }
    }
    Map<ManagedViewType<? extends Object[]>, String> inheritanceSubtypeMappings;
    if (isKey) {
        inheritanceSubtypeMappings = (Map<ManagedViewType<? extends Object[]>, String>) (Map<?, ?>) ((MapAttribute<?, ?, ?>) mappingAttribute).getKeyInheritanceSubtypeMappings();
    } else if (mappingAttribute instanceof PluralAttribute<?, ?, ?>) {
        inheritanceSubtypeMappings = (Map<ManagedViewType<? extends Object[]>, String>) (Map<?, ?>) ((PluralAttribute<?, ?, ?>) mappingAttribute).getElementInheritanceSubtypeMappings();
    } else {
        inheritanceSubtypeMappings = (Map<ManagedViewType<? extends Object[]>, String>) (Map<?, ?>) ((SingularAttribute<?, ?>) mappingAttribute).getInheritanceSubtypeMappings();
    }
    String embeddingViewPath = mapperBuilder.getMapping();
    String oldEmbeddingViewPath = embeddingViewJpqlMacro.getEmbeddingViewPath();
    embeddingViewJpqlMacro.setEmbeddingViewPath(embeddingViewPath);
    ViewTypeObjectBuilderTemplate<Object[]> template = new ViewTypeObjectBuilderTemplate<Object[]>(viewRoot, viewRootAlias, subviewAttributePath, subviewAliasPrefix, subviewMappingPrefix, subviewIdPrefix, subviewTupleIdDescriptor, subviewIdDescriptor, startIndex, endTupleElementsToAdd, viewJpqlMacro, embeddingViewJpqlMacro, inheritanceSubtypeMappings, evm, ef, managedViewType, null, proxyFactory);
    ViewTypeObjectBuilderTemplate<Object[]>[] templates = null;
    if (mappingAttribute.getFetchStrategy() == FetchStrategy.MULTISET) {
        String multisetResultAlias = getMultisetResultAlias(subviewAttributePath);
        mapperBuilder.addMapper(new MultisetTupleElementMapper(template, multisetCorrelationExpression, subviewAttributePath, multisetResultAlias, embeddingViewPath, indexExpression, indexTemplate, createLimiter(mapperBuilder, multisetResultAlias, mappingAttribute)));
        templates = new ViewTypeObjectBuilderTemplate[] { template, indexTemplate };
    } else {
        mapperBuilder.addMappers(template.mappers);
        mapperBuilder.addSecondaryMappers(template.secondaryMappers);
        mapperBuilder.addTupleTransformatorFactory(template.tupleTransformatorFactory);
        mapperBuilder.addTupleTransformerFactory(new SubviewTupleTransformerFactory(subviewAttributePath, template, updatableObjectCache, nullIfEmpty));
    }
    embeddingViewJpqlMacro.setEmbeddingViewPath(oldEmbeddingViewPath);
    viewJpqlMacro.setViewPath(oldViewPath);
    return templates;
}
Also used : ManagedViewType(com.blazebit.persistence.view.metamodel.ManagedViewType) MultisetTupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.MultisetTupleElementMapper) CorrelationMultisetTupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.CorrelationMultisetTupleElementMapper) PluralAttribute(com.blazebit.persistence.view.metamodel.PluralAttribute) ManagedViewTypeImplementor(com.blazebit.persistence.view.impl.metamodel.ManagedViewTypeImplementor) MapAttribute(com.blazebit.persistence.view.metamodel.MapAttribute) SingularAttribute(com.blazebit.persistence.view.metamodel.SingularAttribute) AbstractAttribute(com.blazebit.persistence.view.impl.metamodel.AbstractAttribute) SubviewTupleTransformerFactory(com.blazebit.persistence.view.impl.objectbuilder.transformer.SubviewTupleTransformerFactory) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) HashMap(java.util.HashMap) ManagedViewType(com.blazebit.persistence.view.metamodel.ManagedViewType) ViewType(com.blazebit.persistence.view.metamodel.ViewType)

Aggregations

AbstractAttribute (com.blazebit.persistence.view.impl.metamodel.AbstractAttribute)2 ManagedViewType (com.blazebit.persistence.view.metamodel.ManagedViewType)2 MapAttribute (com.blazebit.persistence.view.metamodel.MapAttribute)2 PluralAttribute (com.blazebit.persistence.view.metamodel.PluralAttribute)2 SingularAttribute (com.blazebit.persistence.view.metamodel.SingularAttribute)2 ViewType (com.blazebit.persistence.view.metamodel.ViewType)2 EntityViewManagerImpl (com.blazebit.persistence.view.impl.EntityViewManagerImpl)1 AttributeAccessor (com.blazebit.persistence.view.impl.accessor.AttributeAccessor)1 ManagedViewTypeImplementor (com.blazebit.persistence.view.impl.metamodel.ManagedViewTypeImplementor)1 CorrelationMultisetTupleElementMapper (com.blazebit.persistence.view.impl.objectbuilder.mapper.CorrelationMultisetTupleElementMapper)1 MultisetTupleElementMapper (com.blazebit.persistence.view.impl.objectbuilder.mapper.MultisetTupleElementMapper)1 SubviewTupleTransformerFactory (com.blazebit.persistence.view.impl.objectbuilder.transformer.SubviewTupleTransformerFactory)1 Type (com.blazebit.persistence.view.metamodel.Type)1 HashMap (java.util.HashMap)1 LinkedHashMap (java.util.LinkedHashMap)1 Map (java.util.Map)1