Search in sources :

Example 1 with AbstractMethodAttribute

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

the class EntityViewUpdaterImpl method createPluralAttributeSubFlusher.

private DirtyAttributeFlusher<?, ?, ?> createPluralAttributeSubFlusher(EntityViewManagerImpl evm, Map<Object, EntityViewUpdaterImpl> localCache, ManagedViewTypeImplementor<?> viewType, AbstractMethodAttribute<?, ?> attribute, String name, Type<?> type, EntityViewUpdaterImpl owner, String ownerMapping) {
    EntityMetamodel entityMetamodel = evm.getMetamodel().getEntityMetamodel();
    String attributeName = attribute.getName() + "_" + name;
    String attributeMapping = attribute.getMapping();
    String attributeLocation = attribute.getLocation();
    Set<Type<?>> readOnlyAllowedSubtypes = attribute.getReadOnlyAllowedSubtypes();
    Set<Type<?>> persistAllowedSubtypes = attribute.getPersistCascadeAllowedSubtypes();
    Set<Type<?>> updateAllowedSubtypes = attribute.getUpdateCascadeAllowedSubtypes();
    if (type instanceof ManagedViewType<?>) {
        ManagedViewTypeImplementor<?> subviewType = (ManagedViewTypeImplementor<?>) type;
        if (!(subviewType.getJpaManagedType() instanceof EntityType<?>)) {
            // A singular attribute where the subview refers to an embeddable type
            EmbeddableUpdaterBasedViewToEntityMapper viewToEntityMapper = new EmbeddableUpdaterBasedViewToEntityMapper(attributeLocation, evm, subviewType.getJavaType(), readOnlyAllowedSubtypes, persistAllowedSubtypes, updateAllowedSubtypes, EntityLoaders.referenceLoaderForAttribute(evm, localCache, subviewType, attribute), false, null, owner, ownerMapping == null ? attributeMapping : ownerMapping + "." + attributeMapping, localCache);
            String parameterName = attributeName + "_";
            String updateFragment = attributeMapping + ".";
            return new EmbeddableAttributeFlusher<>(attributeName, attributeMapping, updateFragment, parameterName, false, false, false, null, null, viewToEntityMapper);
        } else {
            ViewTypeImplementor<?> attributeViewType = (ViewTypeImplementor<?>) subviewType;
            InitialValueAttributeAccessor viewAttributeAccessor = Accessors.forMutableViewAttribute(evm, attribute);
            AttributeAccessor subviewIdAccessor;
            ManagedType<?> ownerManagedType = owner == null ? viewType.getJpaManagedType() : owner.managedViewType.getJpaManagedType();
            EntityType<?> ownerEntityType = ownerManagedType instanceof EntityType<?> ? (EntityType<?>) ownerManagedType : null;
            String attributeElementIdMapping;
            if (ownerEntityType != null && attribute.getMapping() != null) {
                ExtendedManagedType<?> extendedManagedType = evm.getMetamodel().getEntityMetamodel().getManagedType(ExtendedManagedType.class, attributeViewType.getEntityClass());
                attributeElementIdMapping = TypeDescriptor.getAttributeElementIdentifier(evm, ownerEntityType, attribute.getName(), ownerMapping, attribute.getMapping(), extendedManagedType.getType());
            } else {
                attributeElementIdMapping = ((MappingAttribute<?, ?>) attributeViewType.getIdAttribute()).getMapping();
            }
            subviewIdAccessor = Accessors.forSubviewAssociationId(evm, attributeViewType, attributeElementIdMapping, true);
            Attribute<?, ?> attributeIdAttribute = attributeViewType.getJpaManagedType().getAttribute(attributeElementIdMapping);
            javax.persistence.metamodel.Type<?> attributeIdAttributeType = entityMetamodel.type(JpaMetamodelUtils.resolveFieldClass(attributeViewType.getEntityClass(), attributeIdAttribute));
            List<String> idComponentMappings;
            boolean requiresComponentWiseSetInUpdate = true;
            if (requiresComponentWiseSetInUpdate && attributeIdAttributeType instanceof EmbeddableType<?>) {
                // If the identifier used for the association is an embeddable, we must collect the individual attribute components since updates don't work on embeddables directly
                Set<Attribute<?, ?>> idAttributeComponents = (Set<Attribute<?, ?>>) ((EmbeddableType<?>) attributeIdAttributeType).getAttributes();
                idComponentMappings = new ArrayList<>(idAttributeComponents.size());
                for (Attribute<?, ?> idAttributeComponent : idAttributeComponents) {
                    idComponentMappings.add(attributeMapping + "." + attributeElementIdMapping + "." + idAttributeComponent);
                }
            } else {
                idComponentMappings = Collections.singletonList(attributeMapping + "." + attributeElementIdMapping);
            }
            String[] idAttributeMappings = idComponentMappings.toArray(new String[idComponentMappings.size()]);
            ViewToEntityMapper viewToEntityMapper = createViewToEntityMapper(attributeLocation, evm, localCache, ownerEntityType, attributeName, attributeMapping, attributeViewType, false, false, readOnlyAllowedSubtypes, persistAllowedSubtypes, updateAllowedSubtypes, EntityLoaders.referenceLoaderForAttribute(evm, localCache, attributeViewType, attribute.getViewTypes(), attributeElementIdMapping), owner, ownerMapping);
            String parameterName = attributeName;
            return new SubviewAttributeFlusher<>(attributeName, attributeMapping, false, true, false, false, false, subviewType.getConverter(), false, idAttributeMappings, parameterName, false, owner != null, null, viewAttributeAccessor, subviewIdAccessor, viewToEntityMapper, null, null);
        }
    } else {
        TypeDescriptor elementDescriptor = TypeDescriptor.forType(evm, localCache, this, attribute, type, owner, ownerMapping);
        String parameterName = attributeName;
        String updateFragment = attributeMapping;
        // TODO: Why?
        boolean supportsQueryFlush = !elementDescriptor.isJpaEmbeddable();
        return new BasicAttributeFlusher<>(attributeName, attributeMapping, supportsQueryFlush, false, true, false, false, false, null, elementDescriptor, updateFragment, parameterName, null, null, null, null, null);
    }
}
Also used : ViewTypeImplementor(com.blazebit.persistence.view.impl.metamodel.ViewTypeImplementor) ManagedViewTypeImplementor(com.blazebit.persistence.view.impl.metamodel.ManagedViewTypeImplementor) Set(java.util.Set) HashSet(java.util.HashSet) MappingAttribute(com.blazebit.persistence.view.metamodel.MappingAttribute) SingularAttribute(javax.persistence.metamodel.SingularAttribute) Attribute(javax.persistence.metamodel.Attribute) AbstractMethodAttribute(com.blazebit.persistence.view.impl.metamodel.AbstractMethodAttribute) PluralAttribute(com.blazebit.persistence.view.metamodel.PluralAttribute) ExtendedAttribute(com.blazebit.persistence.spi.ExtendedAttribute) MapAttribute(com.blazebit.persistence.view.metamodel.MapAttribute) MethodAttribute(com.blazebit.persistence.view.metamodel.MethodAttribute) InitialValueAttributeAccessor(com.blazebit.persistence.view.impl.accessor.InitialValueAttributeAccessor) EmbeddableAttributeFlusher(com.blazebit.persistence.view.impl.update.flush.EmbeddableAttributeFlusher) LoadOrPersistViewToEntityMapper(com.blazebit.persistence.view.impl.entity.LoadOrPersistViewToEntityMapper) LoadOnlyViewToEntityMapper(com.blazebit.persistence.view.impl.entity.LoadOnlyViewToEntityMapper) SimpleMapViewToEntityMapper(com.blazebit.persistence.view.impl.update.flush.SimpleMapViewToEntityMapper) UpdaterBasedViewToEntityMapper(com.blazebit.persistence.view.impl.entity.UpdaterBasedViewToEntityMapper) EmbeddableUpdaterBasedViewToEntityMapper(com.blazebit.persistence.view.impl.entity.EmbeddableUpdaterBasedViewToEntityMapper) MapViewToEntityMapper(com.blazebit.persistence.view.impl.entity.MapViewToEntityMapper) ViewToEntityMapper(com.blazebit.persistence.view.impl.entity.ViewToEntityMapper) SubviewAttributeFlusher(com.blazebit.persistence.view.impl.update.flush.SubviewAttributeFlusher) ManagedViewType(com.blazebit.persistence.view.metamodel.ManagedViewType) ManagedViewTypeImplementor(com.blazebit.persistence.view.impl.metamodel.ManagedViewTypeImplementor) EntityType(javax.persistence.metamodel.EntityType) ManagedType(javax.persistence.metamodel.ManagedType) BasicType(com.blazebit.persistence.view.metamodel.BasicType) EntityType(javax.persistence.metamodel.EntityType) Type(com.blazebit.persistence.view.metamodel.Type) ExtendedManagedType(com.blazebit.persistence.spi.ExtendedManagedType) VersionBasicUserType(com.blazebit.persistence.view.spi.type.VersionBasicUserType) ManagedViewType(com.blazebit.persistence.view.metamodel.ManagedViewType) EmbeddableType(javax.persistence.metamodel.EmbeddableType) ViewType(com.blazebit.persistence.view.metamodel.ViewType) TypeDescriptor(com.blazebit.persistence.view.impl.update.flush.TypeDescriptor) BasicAttributeFlusher(com.blazebit.persistence.view.impl.update.flush.BasicAttributeFlusher) InitialValueAttributeAccessor(com.blazebit.persistence.view.impl.accessor.InitialValueAttributeAccessor) AttributeAccessor(com.blazebit.persistence.view.impl.accessor.AttributeAccessor) EntityMetamodel(com.blazebit.persistence.parser.EntityMetamodel) EmbeddableUpdaterBasedViewToEntityMapper(com.blazebit.persistence.view.impl.entity.EmbeddableUpdaterBasedViewToEntityMapper)

Example 2 with AbstractMethodAttribute

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

the class ViewTypeObjectBuilderTemplate method addEmbeddingViewMappingIfNeeded.

private int addEmbeddingViewMappingIfNeeded(TupleElementMapperBuilder mapperBuilder, Set<Feature> features, String subviewAliasPrefix, String attributePath, int embeddingViewIndex) {
    if (viewType.getJpaManagedType() instanceof EntityType<?>) {
        boolean embeddingViewMapping = false;
        if (viewType instanceof ViewType<?>) {
            MethodAttribute idAttribute = ((ViewType) viewType).getIdAttribute();
            if (idAttribute.isSubview() || !((AbstractMethodAttribute) idAttribute).isUpdateMappable()) {
                embeddingViewMapping = true;
            }
        } else {
            embeddingViewMapping = true;
        }
        if (embeddingViewMapping) {
            embeddingViewIndex = tupleOffset + mapperBuilder.mapperIndex();
            javax.persistence.metamodel.SingularAttribute<?, ?> singleIdAttribute = JpaMetamodelUtils.getSingleIdAttribute((IdentifiableType<?>) viewType.getJpaManagedType());
            mapperBuilder.addMapper(createMapper((BasicUserTypeStringSupport<?>) null, singleIdAttribute.getName(), subviewAliasPrefix + "_embedding_view_id", attributePath, null, null, EMPTY));
        }
    }
    return embeddingViewIndex;
}
Also used : EntityType(javax.persistence.metamodel.EntityType) AbstractMethodAttribute(com.blazebit.persistence.view.impl.metamodel.AbstractMethodAttribute) MethodAttribute(com.blazebit.persistence.view.metamodel.MethodAttribute) BasicUserTypeStringSupport(com.blazebit.persistence.view.spi.type.BasicUserTypeStringSupport) AbstractMethodAttribute(com.blazebit.persistence.view.impl.metamodel.AbstractMethodAttribute) ManagedViewType(com.blazebit.persistence.view.metamodel.ManagedViewType) ViewType(com.blazebit.persistence.view.metamodel.ViewType)

Example 3 with AbstractMethodAttribute

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

the class EntityViewSettingHelper method applyAttributeSorters.

private static <T, Q extends FullQueryBuilder<T, Q>> void applyAttributeSorters(EntityViewSetting<?, ?> setting, Q cb, String viewRoot, Set<String> fetches, ManagedViewTypeImplementor<?> entityViewRoot) {
    String name = entityViewRoot.getJavaType().getSimpleName();
    StringBuilder sb = null;
    for (Map.Entry<String, Sorter> attributeSorterEntry : setting.getAttributeSorters().entrySet()) {
        String attributeName = attributeSorterEntry.getKey();
        NavigableMap<String, AbstractMethodAttribute<?, ?>> recursiveAttributes = (NavigableMap<String, AbstractMethodAttribute<?, ?>>) entityViewRoot.getRecursiveAttributes();
        Map.Entry<String, AbstractMethodAttribute<?, ?>> entry = recursiveAttributes.floorEntry(attributeName);
        if (entry == null || !attributeName.startsWith(entry.getKey())) {
            throw new IllegalArgumentException("The attribute with the name '" + attributeName + "' couldn't be found on the view type '" + name + "'");
        }
        if (attributeName.length() != entry.getKey().length()) {
            throw new UnsupportedOperationException("No support yet for entity attribute filtering!");
        // // If we get here, the attribute type is a managed type and we can copy the rest of the parts
        // for (; i < parts.length; i++) {
        // type = jpaMetamodel.managedType(maybeUnmanagedType);
        // newSb.append('.');
        // newSb.append(parts[i]);
        // jpaAttribute = type.getAttribute(parts[i]);
        // maybeUnmanagedType = jpaAttribute.getJavaType();
        // }
        }
        Sorter sorter = attributeSorterEntry.getValue();
        if (sb == null) {
            sb = new StringBuilder(name.length() + attributeName.length() + 1);
        } else {
            sb.setLength(0);
        }
        String attributeExpression;
        if (fetches.isEmpty() || fetches.contains(attributeName)) {
            attributeExpression = buildAlias(sb, name, attributeName);
        } else {
            attributeExpression = buildMapping(sb, cb, viewRoot, recursiveAttributes, attributeName);
        }
        sorter.apply(cb, attributeExpression);
    }
}
Also used : NavigableMap(java.util.NavigableMap) Sorter(com.blazebit.persistence.view.Sorter) AbstractMethodAttribute(com.blazebit.persistence.view.impl.metamodel.AbstractMethodAttribute) HashMap(java.util.HashMap) Map(java.util.Map) NavigableMap(java.util.NavigableMap)

Example 4 with AbstractMethodAttribute

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

the class ProxyFactory method addReplaceAttribute.

private CtMethod addReplaceAttribute(CtClass cc, AbstractMethodAttribute[] attributes) throws CannotCompileException {
    String desc = "(" + Descriptor.of(Object.class.getName()) + "I" + Descriptor.of(Object.class.getName()) + ")V";
    ConstPool cp = cc.getClassFile().getConstPool();
    MethodInfo minfo = new MethodInfo(cp, "$$_replaceAttribute", desc);
    minfo.setAccessFlags(AccessFlag.PUBLIC);
    StringBuilder sb = new StringBuilder();
    sb.append("{\n");
    sb.append("\tswitch ($2) {");
    for (int i = 0; i < attributes.length; i++) {
        AbstractMethodAttribute attribute = attributes[i];
        if (attribute != null && attribute.hasDirtyStateIndex()) {
            sb.append("\t\tcase ").append(attribute.getDirtyStateIndex()).append(": ");
            // If there is no setter, we simply ignore the object rather than throwing an exception
            if (ReflectionUtils.getSetter(attribute.getDeclaringType().getJavaType(), attribute.getName()) != null) {
                sb.append("$0.set").append(Character.toUpperCase(attribute.getName().charAt(0))).append(attribute.getName(), 1, attribute.getName().length());
                sb.append('(');
                if (attribute.getConvertedJavaType().isPrimitive()) {
                    appendUnwrap(sb, attribute.getConvertedJavaType(), "$3");
                } else {
                    sb.append("(").append(attribute.getConvertedJavaType().getCanonicalName()).append(") $3");
                }
                sb.append("); ");
            }
            sb.append("break;\n");
        }
    }
    sb.append("\t\tdefault: throw new IllegalArgumentException(\"Invalid non-mutable attribute index: \" + $2);\n");
    sb.append("\t}\n");
    sb.append('}');
    CtMethod method = CtMethod.make(minfo, cc);
    method.setBody(sb.toString());
    cc.addMethod(method);
    return method;
}
Also used : ConstPool(javassist.bytecode.ConstPool) AbstractMethodAttribute(com.blazebit.persistence.view.impl.metamodel.AbstractMethodAttribute) MethodInfo(javassist.bytecode.MethodInfo) CtMethod(javassist.CtMethod)

Example 5 with AbstractMethodAttribute

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

the class ProxyFactory method createSerializationSubclass.

private void createSerializationSubclass(ManagedViewTypeImplementor<?> managedViewType, CtClass cc) throws Exception {
    boolean hasSelfConstructor = false;
    OUTER: for (MappingConstructor<?> constructor : managedViewType.getConstructors()) {
        for (ParameterAttribute<?, ?> parameterAttribute : constructor.getParameterAttributes()) {
            if (parameterAttribute.isSelfParameter()) {
                hasSelfConstructor = true;
                break OUTER;
            }
        }
    }
    if (hasSelfConstructor) {
        String serializableClassName = cc.getName() + "Ser";
        Set<AbstractMethodAttribute<?, ?>> attributes = (Set<AbstractMethodAttribute<?, ?>>) (Set<?>) managedViewType.getAttributes();
        CtClass[] attributeTypes = new CtClass[attributes.size()];
        createSerializableClass(managedViewType, cc, serializableClassName, attributes, attributeTypes);
        ConstPool cp = cc.getClassFile().getConstPool();
        MethodInfo minfo = new MethodInfo(cp, "createSelf", Descriptor.ofMethod(pool.get(managedViewType.getJavaType().getName()), attributeTypes));
        CtMethod method = CtMethod.make(minfo, cc);
        minfo.setAccessFlags(AccessFlag.PUBLIC | AccessFlag.STATIC);
        StringBuilder sb = new StringBuilder();
        sb.append("{\n");
        sb.append("\t").append(serializableClassName).append(" self = (").append(serializableClassName).append(") new java.io.ObjectInputStream(new java.io.ByteArrayInputStream(");
        sb.append(serializableClassName).append(".EMPTY_INSTANCE_BYTES)).readObject();\n");
        int index = 1;
        for (MethodAttribute<?, ?> attribute : attributes) {
            sb.append("\tself.").append(attribute.getName()).append(" = $").append(index).append(";\n");
            index++;
        }
        sb.append("\treturn self;\n");
        sb.append("}");
        method.setBody(sb.toString());
        cc.addMethod(method);
    }
}
Also used : ParameterAttribute(com.blazebit.persistence.view.metamodel.ParameterAttribute) ConstPool(javassist.bytecode.ConstPool) RecordingNavigableSet(com.blazebit.persistence.view.impl.collection.RecordingNavigableSet) Set(java.util.Set) LinkedHashSet(java.util.LinkedHashSet) RecordingSet(com.blazebit.persistence.view.impl.collection.RecordingSet) MappingConstructor(com.blazebit.persistence.view.metamodel.MappingConstructor) CtClass(javassist.CtClass) AbstractMethodAttribute(com.blazebit.persistence.view.impl.metamodel.AbstractMethodAttribute) MethodInfo(javassist.bytecode.MethodInfo) CtMethod(javassist.CtMethod)

Aggregations

AbstractMethodAttribute (com.blazebit.persistence.view.impl.metamodel.AbstractMethodAttribute)10 MethodAttribute (com.blazebit.persistence.view.metamodel.MethodAttribute)6 Set (java.util.Set)5 ManagedViewType (com.blazebit.persistence.view.metamodel.ManagedViewType)4 ViewType (com.blazebit.persistence.view.metamodel.ViewType)4 EntityType (javax.persistence.metamodel.EntityType)4 ExtendedAttribute (com.blazebit.persistence.spi.ExtendedAttribute)3 AttributeAccessor (com.blazebit.persistence.view.impl.accessor.AttributeAccessor)3 InitialValueAttributeAccessor (com.blazebit.persistence.view.impl.accessor.InitialValueAttributeAccessor)3 BasicAttributeFlusher (com.blazebit.persistence.view.impl.update.flush.BasicAttributeFlusher)3 EmbeddableAttributeFlusher (com.blazebit.persistence.view.impl.update.flush.EmbeddableAttributeFlusher)3 TypeDescriptor (com.blazebit.persistence.view.impl.update.flush.TypeDescriptor)3 MapAttribute (com.blazebit.persistence.view.metamodel.MapAttribute)3 MappingAttribute (com.blazebit.persistence.view.metamodel.MappingAttribute)3 PluralAttribute (com.blazebit.persistence.view.metamodel.PluralAttribute)3 HashMap (java.util.HashMap)3 LinkedHashMap (java.util.LinkedHashMap)3 EntityMetamodel (com.blazebit.persistence.parser.EntityMetamodel)2 ExtendedManagedType (com.blazebit.persistence.spi.ExtendedManagedType)2 RecordingList (com.blazebit.persistence.view.impl.collection.RecordingList)2