Search in sources :

Example 1 with EntityViewRootMapping

use of com.blazebit.persistence.view.spi.EntityViewRootMapping in project blaze-persistence by Blazebit.

the class AnnotationMappingReader method readViewMapping.

@Override
public ViewMapping readViewMapping(Class<?> entityViewClass) {
    ViewMapping existingMapping = context.getViewMapping(entityViewClass);
    if (existingMapping != null) {
        return existingMapping;
    }
    EntityView entityView = AnnotationUtils.findAnnotation(entityViewClass, EntityView.class);
    if (entityView == null) {
        return null;
    }
    Class<?> entityClass = entityView.value();
    ViewMapping viewMapping = new ViewMappingImpl(entityViewClass, entityClass, context);
    context.addViewMapping(entityViewClass, viewMapping);
    boolean isAbstract = entityViewClass.isInterface() || Modifier.isAbstract(entityViewClass.getModifiers());
    BatchFetch batchFetch = AnnotationUtils.findAnnotation(entityViewClass, BatchFetch.class);
    if (batchFetch != null) {
        viewMapping.setDefaultBatchSize(batchFetch.size());
    }
    Set<Class<? extends CTEProvider>> cteProviders = new LinkedHashSet<>();
    Map<String, Class<? extends ViewFilterProvider>> viewFilterProviders = new HashMap<>();
    Map<String, EntityViewRootMapping> viewRootMappings = new LinkedHashMap<>();
    for (Annotation a : AnnotationUtils.getAllAnnotations(entityViewClass)) {
        if (a instanceof With) {
            cteProviders.addAll(Arrays.asList(((With) a).value()));
        } else if (a instanceof ViewFilter) {
            ViewFilter viewFilter = (ViewFilter) a;
            addFilterMapping(viewFilter.name(), viewFilter.value(), viewFilterProviders, entityViewClass, context);
        } else if (a instanceof ViewFilters) {
            ViewFilters viewFilters = (ViewFilters) a;
            for (ViewFilter viewFilter : viewFilters.value()) {
                addFilterMapping(viewFilter.name(), viewFilter.value(), viewFilterProviders, entityViewClass, context);
            }
        } else if (a instanceof EntityViewRoot) {
            EntityViewRoot entityViewRoot = (EntityViewRoot) a;
            addEntityViewRootMapping(entityViewRoot, viewRootMappings, entityViewClass, context);
        } else if (a instanceof EntityViewRoots) {
            EntityViewRoots entityViewRoots = (EntityViewRoots) a;
            for (EntityViewRoot entityViewRoot : entityViewRoots.value()) {
                addEntityViewRootMapping(entityViewRoot, viewRootMappings, entityViewClass, context);
            }
        }
    }
    viewMapping.setCteProviders(cteProviders);
    viewMapping.setViewFilterProviders(viewFilterProviders);
    viewMapping.setEntityViewRoots(viewRootMappings.isEmpty() ? Collections.<EntityViewRootMapping>emptySet() : new LinkedHashSet<>(viewRootMappings.values()));
    UpdatableEntityView updatableEntityView = AnnotationUtils.findAnnotation(entityViewClass, UpdatableEntityView.class);
    if (updatableEntityView != null) {
        if (isAbstract) {
            viewMapping.setUpdatable(true);
            viewMapping.setFlushMode(updatableEntityView.mode());
            viewMapping.setFlushStrategy(updatableEntityView.strategy());
            viewMapping.setLockMode(updatableEntityView.lockMode());
        } else {
            context.addError("Only abstract class entity views can be updatable! Remove the @UpdatableEntityView annotation from the entity view class '" + entityViewClass.getName() + "' or make it abstract.");
        }
    }
    CreatableEntityView creatableEntityView = AnnotationUtils.findAnnotation(entityViewClass, CreatableEntityView.class);
    if (creatableEntityView != null) {
        if (isAbstract) {
            viewMapping.setCreatable(true);
            viewMapping.setValidatePersistability(creatableEntityView.validatePersistability());
            viewMapping.getExcludedAttributes().addAll(Arrays.asList(creatableEntityView.excludedEntityAttributes()));
        } else {
            context.addError("Only abstract class entity views can be creatable! Remove the @CreatableEntityView annotation from the entity view class '" + entityViewClass.getName() + "' or make it abstract.");
        }
    }
    if (updatableEntityView != null || creatableEntityView != null) {
        LockOwner lockOwner = AnnotationUtils.findAnnotation(entityViewClass, LockOwner.class);
        if (lockOwner != null) {
            viewMapping.setLockOwner(lockOwner.value());
        }
    } else {
        viewMapping.setLockMode(LockMode.NONE);
    }
    // Inheritance
    // Note that the usage of Class.getAnnotation is on purpose
    // For the full discussion see: https://github.com/Blazebit/blaze-persistence/issues/475
    EntityViewInheritance inheritanceAnnotation = entityViewClass.getAnnotation(EntityViewInheritance.class);
    EntityViewInheritanceMapping inheritanceMappingAnnotation = entityViewClass.getAnnotation(EntityViewInheritanceMapping.class);
    String inheritanceMapping;
    if (inheritanceMappingAnnotation != null) {
        inheritanceMapping = inheritanceMappingAnnotation.value();
    } else {
        inheritanceMapping = null;
    }
    if (isAbstract) {
        viewMapping.setInheritanceMapping(inheritanceMapping);
        if (inheritanceAnnotation == null) {
            viewMapping.setInheritanceSubtypesResolved(true);
        } else if (inheritanceAnnotation.value().length > 0) {
            viewMapping.getInheritanceSubtypeClasses().addAll(Arrays.asList(inheritanceAnnotation.value()));
            viewMapping.setInheritanceSubtypesResolved(true);
        }
    } else if (inheritanceMapping != null || inheritanceAnnotation != null) {
        context.addError("Only abstract class entity views can use inheritance mappings! Remove the inheritance annotations from the entity view class '" + entityViewClass.getName() + "' or make it abstract.");
    } else {
        viewMapping.setInheritanceSubtypesResolved(true);
    }
    // Attributes
    if (isAbstract) {
        readAbstractClassMappings(entityViewClass, viewMapping);
    } else {
        readClassMappings(entityViewClass, viewMapping);
    }
    return viewMapping;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) LockOwner(com.blazebit.persistence.view.LockOwner) LinkedHashMap(java.util.LinkedHashMap) With(com.blazebit.persistence.view.With) EntityViewRoots(com.blazebit.persistence.view.EntityViewRoots) ViewFilter(com.blazebit.persistence.view.ViewFilter) CreatableEntityView(com.blazebit.persistence.view.CreatableEntityView) ViewFilters(com.blazebit.persistence.view.ViewFilters) CTEProvider(com.blazebit.persistence.view.CTEProvider) UpdatableEntityView(com.blazebit.persistence.view.UpdatableEntityView) EntityView(com.blazebit.persistence.view.EntityView) UpdatableEntityView(com.blazebit.persistence.view.UpdatableEntityView) CreatableEntityView(com.blazebit.persistence.view.CreatableEntityView) EntityViewInheritanceMapping(com.blazebit.persistence.view.EntityViewInheritanceMapping) EntityViewRoot(com.blazebit.persistence.view.EntityViewRoot) Annotation(java.lang.annotation.Annotation) BatchFetch(com.blazebit.persistence.view.BatchFetch) ViewFilterProvider(com.blazebit.persistence.view.ViewFilterProvider) CtClass(javassist.CtClass) EntityViewRootMapping(com.blazebit.persistence.view.spi.EntityViewRootMapping) EntityViewInheritance(com.blazebit.persistence.view.EntityViewInheritance)

Example 2 with EntityViewRootMapping

use of com.blazebit.persistence.view.spi.EntityViewRootMapping in project blaze-persistence by Blazebit.

the class ViewMappingImpl method initViewRoots.

private void initViewRoots(MetamodelBuildingContext context) {
    if (entityViewRoots == null || entityViewRoots.isEmpty()) {
        this.viewRoots = Collections.emptySet();
        this.viewRootTypes = Collections.emptyMap();
    } else {
        this.viewRoots = new LinkedHashSet<>(entityViewRoots.size());
        this.viewRootTypes = new HashMap<>(entityViewRoots.size());
        Set<String> rootAliases = new HashSet<>(entityViewRoots.size());
        for (EntityViewRootMapping entityViewRoot : entityViewRoots) {
            rootAliases.add(entityViewRoot.getName());
        }
        for (EntityViewRootMapping entityViewRoot : entityViewRoots) {
            String viewRootName = entityViewRoot.getName();
            Class<?> entityClass = entityViewRoot.getManagedTypeClass();
            String joinExpression = entityViewRoot.getJoinExpression();
            Class<? extends CorrelationProvider> correlationProvider = entityViewRoot.getCorrelationProvider();
            CorrelationProviderFactory correlationProviderFactory = null;
            javax.persistence.metamodel.Type<?> type = null;
            String conditionExpression = entityViewRoot.getConditionExpression();
            if (entityClass != null) {
                if (joinExpression != null || correlationProvider != null) {
                    context.addError("Illegal entity view root mapping '" + viewRootName + "' at the class '" + entityViewClass.getName() + "'! Only one of the attributes entity, expression or correlator may be used!");
                }
                if (conditionExpression == null) {
                    context.addError("Illegal entity view root mapping '" + viewRootName + "' at the class '" + entityViewClass.getName() + "'! When using the entity attribute, a condition expression is required!");
                } else {
                    correlationProviderFactory = new StaticCorrelationProvider(entityClass, viewRootName, conditionExpression, createPredicate(conditionExpression, context, viewRootName), rootAliases);
                }
            } else if (joinExpression != null) {
                if (correlationProvider != null) {
                    context.addError("Illegal entity view root mapping '" + viewRootName + "' at the class '" + entityViewClass.getName() + "'! Only one of the attributes entity, expression or correlator may be used!");
                }
                if (conditionExpression == null) {
                    correlationProviderFactory = new StaticPathCorrelationProvider(joinExpression, viewRootName, "1=1", createPredicate("1=1", context, viewRootName), rootAliases);
                } else {
                    correlationProviderFactory = new StaticPathCorrelationProvider(joinExpression, viewRootName, conditionExpression, createPredicate(conditionExpression, context, viewRootName), rootAliases);
                }
            } else if (correlationProvider != null) {
                if (conditionExpression != null) {
                    context.addError("Illegal entity view root mapping '" + viewRootName + "' at the class '" + entityViewClass.getName() + "'! When using the correlator attribute, using a condition expression is illegal!");
                }
                correlationProviderFactory = CorrelationProviderHelper.getFactory(correlationProvider);
            } else {
                context.addError("Illegal entity view root mapping '" + viewRootName + "' at the class '" + entityViewClass.getName() + "'! One of the attributes entity, expression or correlator must be used for a valid entity view root definition!");
            }
            String limitExpression;
            String offsetExpression;
            List<OrderByItem> orderByItems;
            if (entityViewRoot.getLimitExpression() == null || entityViewRoot.getLimitExpression().isEmpty()) {
                limitExpression = null;
                offsetExpression = null;
                orderByItems = Collections.emptyList();
            } else {
                limitExpression = entityViewRoot.getLimitExpression();
                offsetExpression = entityViewRoot.getOffsetExpression();
                if (offsetExpression == null || offsetExpression.isEmpty()) {
                    offsetExpression = "0";
                }
                List<String> orderByItemExpressions = entityViewRoot.getOrderByItems();
                orderByItems = AbstractAttribute.parseOrderByItems(orderByItemExpressions);
            }
            try {
                type = TypeExtractingCorrelationBuilder.extractType(correlationProviderFactory, viewRootName, context, new ScalarTargetResolvingExpressionVisitor(getManagedType(context), context.getEntityMetamodel(), context.getJpqlFunctions(), viewRootTypes));
            } catch (Exception ex) {
                StringWriter sw = new StringWriter();
                sw.append("Illegal entity view root mapping '").append(viewRootName).append("' at the class '").append(entityViewClass.getName()).append("'! The given entity class is not a valid managed type:\n");
                ex.printStackTrace(new PrintWriter(sw));
                context.addError(sw.toString());
            }
            viewRootTypes.put(viewRootName, type);
            viewRoots.add(new ViewRootImpl(viewRootName, type, correlationProviderFactory, correlationProvider, entityViewRoot.getJoinType(), entityViewRoot.getFetches(), orderByItems, limitExpression, offsetExpression));
        }
    }
}
Also used : ScalarTargetResolvingExpressionVisitor(com.blazebit.persistence.view.impl.ScalarTargetResolvingExpressionVisitor) SyntaxErrorException(com.blazebit.persistence.parser.expression.SyntaxErrorException) OrderByItem(com.blazebit.persistence.view.metamodel.OrderByItem) CorrelationProviderFactory(com.blazebit.persistence.view.CorrelationProviderFactory) StringWriter(java.io.StringWriter) StaticPathCorrelationProvider(com.blazebit.persistence.view.impl.StaticPathCorrelationProvider) EntityViewRootMapping(com.blazebit.persistence.view.spi.EntityViewRootMapping) StaticCorrelationProvider(com.blazebit.persistence.view.impl.StaticCorrelationProvider) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) PrintWriter(java.io.PrintWriter)

Aggregations

EntityViewRootMapping (com.blazebit.persistence.view.spi.EntityViewRootMapping)2 LinkedHashSet (java.util.LinkedHashSet)2 SyntaxErrorException (com.blazebit.persistence.parser.expression.SyntaxErrorException)1 BatchFetch (com.blazebit.persistence.view.BatchFetch)1 CTEProvider (com.blazebit.persistence.view.CTEProvider)1 CorrelationProviderFactory (com.blazebit.persistence.view.CorrelationProviderFactory)1 CreatableEntityView (com.blazebit.persistence.view.CreatableEntityView)1 EntityView (com.blazebit.persistence.view.EntityView)1 EntityViewInheritance (com.blazebit.persistence.view.EntityViewInheritance)1 EntityViewInheritanceMapping (com.blazebit.persistence.view.EntityViewInheritanceMapping)1 EntityViewRoot (com.blazebit.persistence.view.EntityViewRoot)1 EntityViewRoots (com.blazebit.persistence.view.EntityViewRoots)1 LockOwner (com.blazebit.persistence.view.LockOwner)1 UpdatableEntityView (com.blazebit.persistence.view.UpdatableEntityView)1 ViewFilter (com.blazebit.persistence.view.ViewFilter)1 ViewFilterProvider (com.blazebit.persistence.view.ViewFilterProvider)1 ViewFilters (com.blazebit.persistence.view.ViewFilters)1 With (com.blazebit.persistence.view.With)1 ScalarTargetResolvingExpressionVisitor (com.blazebit.persistence.view.impl.ScalarTargetResolvingExpressionVisitor)1 StaticCorrelationProvider (com.blazebit.persistence.view.impl.StaticCorrelationProvider)1