All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.micronaut.annotation.processing.test.AbstractEvaluatedExpressionsSpec.groovy Maven / Gradle / Ivy
/*
* Copyright 2017-2022 original authors
*
* 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
*
* https://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 io.micronaut.annotation.processing.test
import io.micronaut.context.expressions.AbstractEvaluatedExpression
import io.micronaut.context.expressions.DefaultExpressionEvaluationContext
import io.micronaut.core.expressions.EvaluatedExpressionReference
import io.micronaut.core.naming.NameUtils
import io.micronaut.expressions.util.EvaluatedExpressionsUtils
import io.micronaut.inject.annotation.EvaluatedExpressionReferenceCounter
import io.micronaut.inject.ast.ClassElement
import io.micronaut.inject.ast.MethodElement
import io.micronaut.inject.visitor.TypeElementVisitor
import io.micronaut.inject.visitor.VisitorContext
import org.intellij.lang.annotations.Language
abstract class AbstractEvaluatedExpressionsSpec extends AbstractTypeElementSpec {
@Override
protected Collection getLocalTypeElementVisitors() {
return [new ContextRegistrar(), new ExpressionTypeCollector()]
}
List evaluateMultiple(String... expressions) {
String classContent = ""
for (int i = 0; i < expressions.size(); i++) {
classContent += """
@Value("${expressions[i]}")
public Object field${i};
"""
}
def cls = """
package test;
import io.micronaut.context.annotation.Value;
class Expr {
${classContent}
}
""".stripIndent().stripLeading()
def applicationContext = buildContext(cls)
def classLoader = applicationContext.classLoader
def exprClassName = 'test.$Expr$Expr'
def startingIndex = EvaluatedExpressionReferenceCounter.nextIndex(exprClassName) - expressions.length
List result = new ArrayList<>()
for (int i = startingIndex; i < startingIndex + expressions.size(); i++) {
String exprFullName = exprClassName + i
try {
def exprClass = (AbstractEvaluatedExpression) classLoader.loadClass(exprFullName).newInstance()
result.add(exprClass.evaluate(new DefaultExpressionEvaluationContext(null, null, applicationContext, null)))
} catch (ClassNotFoundException e) {
return null
}
}
return result
}
Object evaluate(String expression) {
return evaluateAgainstContext(expression, "")
}
Object evaluateAgainstContext(String expression, @Language("java") String contextClass) {
String exprFullName = 'test.$Expr$Expr';
def cls = """
package test;
import io.micronaut.context.annotation.Value;
import jakarta.inject.Singleton;
${contextClass}
@Singleton
class Expr {
@Value("${expression}")
public Object field;
}
""".stripIndent().stripLeading()
def applicationContext = buildContext(cls)
def classLoader = applicationContext.classLoader
try {
def index = EvaluatedExpressionReferenceCounter.nextIndex(exprFullName)
def exprClass = (AbstractEvaluatedExpression) classLoader.loadClass(exprFullName + (index == 0 ? index : index - 1)).newInstance()
exprClass.evaluate(new DefaultExpressionEvaluationContext(null, null, applicationContext, null))
} catch (ClassNotFoundException e) {
return null
}
}
Object evaluateMultipleAgainstContext(@Language("java") String contextClass, String... expressions) {
String expr = ""
for (int i = 0; i < expressions.length; i++) {
expr += """
@Value("${expressions[i]}")
public Object field${i};
"""
}
def cls = """
package test;
import io.micronaut.context.annotation.Value;
import jakarta.inject.Singleton;
${contextClass}
@Singleton
class Expr {
${expr}
}
""".stripIndent().stripLeading()
def applicationContext = buildContext(cls)
def classLoader = applicationContext.classLoader
def exprClassName = 'test.$Expr$Expr'
def startingIndex = EvaluatedExpressionReferenceCounter.nextIndex(exprClassName) - expressions.length
List result = new ArrayList<>()
for (int i = startingIndex; i < startingIndex + expressions.size(); i++) {
String exprFullName = exprClassName + i
try {
def exprClass = (AbstractEvaluatedExpression) classLoader.loadClass(exprFullName).newInstance()
result.add(exprClass.evaluate(new DefaultExpressionEvaluationContext(null, null, applicationContext,
null)))
} catch (ClassNotFoundException e) {
return null
}
}
return result
}
Object evaluateSingle(String className,
@Language("java") String cls) {
return evaluateSingle(className, cls, null)
}
Object evaluateSingle(String className,
@Language("java") String cls,
Object[] args) {
def classSimpleName = NameUtils.getSimpleName(className)
def packageName = NameUtils.getPackageName(className)
def exprClassName = (classSimpleName.startsWith('$') ? '' : '$') + classSimpleName + '$Expr'
String exprFullName = "${packageName}.${exprClassName}"
def applicationContext = buildContext(cls)
def classLoader = applicationContext.classLoader
try {
def index = EvaluatedExpressionReferenceCounter.nextIndex(exprFullName)
def exprClass = (AbstractEvaluatedExpression) classLoader.loadClass(exprFullName + (index == 0 ? index : index - 1)).newInstance()
return exprClass.evaluate(new DefaultExpressionEvaluationContext(null, args, applicationContext, null))
} catch (ClassNotFoundException e) {
return null
}
}
static class ContextRegistrar implements TypeElementVisitor {
static final List CLASSES = ["test.Context"]
static void setClasses(String...classes) {
CLASSES.clear()
CLASSES.addAll(classes)
}
static void reset() {
CLASSES.clear()
CLASSES.add("test.Context")
}
@Override
void start(VisitorContext visitorContext) {
for (cls in CLASSES) {
visitorContext.getClassElement(cls).ifPresent {
visitorContext.expressionCompilationContextFactory.registerContextClass(it)
}
}
}
}
static class ExpressionTypeCollector implements TypeElementVisitor {
static final Map TYPES = [:]
@Override
void visitClass(ClassElement element, VisitorContext context) {
def annotation = element.getAnnotation("exp.ExpAnnotation")
if (annotation != null) {
EvaluatedExpressionReference reference = annotation.getValues().get("value") as EvaluatedExpressionReference;
TYPES.put(
reference.annotationValue() as String,
EvaluatedExpressionsUtils.evaluateExpressionType(context, element, reference)
)
}
}
@Override
void visitMethod(MethodElement element, VisitorContext context) {
def annotation = element.getAnnotation("exp.ExpAnnotation")
if (annotation != null) {
EvaluatedExpressionReference reference = annotation.getValues().get("value") as EvaluatedExpressionReference;
TYPES.put(
reference.annotationValue() as String,
EvaluatedExpressionsUtils.evaluateExpressionType(context, element, reference)
)
}
}
}
}