/*
* Copyright 2014 - 2017 Blazebit.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.blazebit.persistence.view.impl.metamodel;
import com.blazebit.persistence.impl.EntityMetamodel;
import com.blazebit.persistence.impl.expression.AbstractCachingExpressionFactory;
import com.blazebit.persistence.impl.expression.ExpressionFactory;
import com.blazebit.persistence.impl.expression.MacroConfiguration;
import com.blazebit.persistence.impl.expression.MacroFunction;
import com.blazebit.persistence.spi.JpqlFunction;
import com.blazebit.persistence.view.impl.JpqlMacroAdapter;
import com.blazebit.persistence.view.impl.MacroConfigurationExpressionFactory;
import com.blazebit.persistence.view.impl.macro.DefaultViewRootJpqlMacro;
import com.blazebit.persistence.view.impl.proxy.ProxyFactory;
import com.blazebit.persistence.view.metamodel.Type;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
*
* @author Christian Beikov
* @since 1.2.0
*/
public class MetamodelBuildingContextImpl implements MetamodelBuildingContext {
private final Map<Class<?>, Type<?>> basicTypeRegistry = new HashMap<>();
private final EntityMetamodel entityMetamodel;
private final Map<String, JpqlFunction> jpqlFunctions;
private final ExpressionFactory expressionFactory;
private final ProxyFactory proxyFactory;
private final Set<Class<?>> entityViewClasses;
private final Set<String> errors;
public MetamodelBuildingContextImpl(EntityMetamodel entityMetamodel, Map<String, JpqlFunction> jpqlFunctions, ExpressionFactory expressionFactory, ProxyFactory proxyFactory, Set<Class<?>> entityViewClasses, Set<String> errors) {
this.entityMetamodel = entityMetamodel;
this.jpqlFunctions = jpqlFunctions;
this.expressionFactory = expressionFactory;
this.proxyFactory = proxyFactory;
this.entityViewClasses = entityViewClasses;
this.errors = errors;
}
@Override
@SuppressWarnings("unchecked")
public <X> Type<X> getBasicType(Class<X> basicClass) {
if (basicClass == null) {
return null;
}
Type<?> t = basicTypeRegistry.get(basicClass);
if (t == null) {
t = new BasicTypeImpl<>(basicClass);
basicTypeRegistry.put(basicClass, t);
}
return (Type<X>) t;
}
@Override
public Map<String, JpqlFunction> getJpqlFunctions() {
return jpqlFunctions;
}
@Override
public EntityMetamodel getEntityMetamodel() {
return entityMetamodel;
}
@Override
public ExpressionFactory getExpressionFactory() {
return expressionFactory;
}
@Override
public ExpressionFactory createMacroAwareExpressionFactory() {
return createMacroAwareExpressionFactory("syntax_checking_placeholder");
}
@Override
public ExpressionFactory createMacroAwareExpressionFactory(String viewRoot) {
MacroConfiguration originalMacroConfiguration = expressionFactory.getDefaultMacroConfiguration();
ExpressionFactory cachingExpressionFactory = expressionFactory.unwrap(AbstractCachingExpressionFactory.class);
MacroFunction macro = new JpqlMacroAdapter(new DefaultViewRootJpqlMacro(viewRoot), cachingExpressionFactory);
MacroConfiguration macroConfiguration = originalMacroConfiguration.with(Collections.singletonMap("view_root", macro));
return new MacroConfigurationExpressionFactory(cachingExpressionFactory, macroConfiguration);
}
@Override
public ProxyFactory getProxyFactory() {
return proxyFactory;
}
@Override
public void addError(String error) {
errors.add(error);
}
@Override
public boolean hasErrors() {
return !errors.isEmpty();
}
@Override
public boolean isEntityView(Class<?> clazz) {
return entityViewClasses.contains(clazz);
}
@Override
public Set<Class<?>> findSubtypes(Class<?> entityViewClass) {
Set<Class<?>> subtypes = new HashSet<>();
for (Class<?> clazz : entityViewClasses) {
if (entityViewClass.isAssignableFrom(clazz) && entityViewClass != clazz) {
subtypes.add(clazz);
}
}
return subtypes;
}
}