io.micronaut.context.RequiresCondition Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2017-2020 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.context;
import io.micronaut.context.annotation.Requires;
import io.micronaut.context.condition.Condition;
import io.micronaut.context.condition.ConditionContext;
import io.micronaut.context.conditions.MatchesConditionUtils;
import io.micronaut.core.annotation.AnnotationMetadata;
import io.micronaut.core.annotation.AnnotationMetadataProvider;
import io.micronaut.core.annotation.AnnotationValue;
import io.micronaut.core.annotation.NextMajorVersion;
import io.micronaut.inject.BeanDefinitionReference;
import java.util.ArrayList;
import java.util.List;
/**
* An abstract {@link Condition} implementation that is based on the presence
* of {@link Requires} annotation.
*
* @author graemerocher
* @since 1.0.0
*/
@NextMajorVersion("Make internal")
public class RequiresCondition implements Condition {
public static final String MEMBER_PROPERTY = "property";
public static final String MEMBER_NOT_EQUALS = "notEquals";
public static final String MEMBER_DEFAULT_VALUE = "defaultValue";
public static final String MEMBER_PATTERN = "pattern";
public static final String MEMBER_MISSING_PROPERTY = "missingProperty";
public static final String MEMBER_ENV = "env";
public static final String MEMBER_NOT_ENV = "notEnv";
public static final String MEMBER_CONDITION = "condition";
public static final String MEMBER_SDK = "sdk";
public static final String MEMBER_VERSION = "version";
public static final String MEMBER_MISSING_CLASSES = "missing";
public static final String MEMBER_RESOURCES = "resources";
public static final String MEMBER_CONFIGURATION = "configuration";
public static final String MEMBER_CLASSES = "classes";
public static final String MEMBER_ENTITIES = "entities";
public static final String MEMBER_BEANS = "beans";
public static final String MEMBER_MISSING_BEANS = "missingBeans";
public static final String MEMBER_OS = "os";
public static final String MEMBER_NOT_OS = "notOs";
public static final String MEMBER_BEAN = "bean";
public static final String MEMBER_BEAN_PROPERTY = "beanProperty";
private final AnnotationMetadata annotationMetadata;
/**
* @param annotationMetadata The annotation metadata
*/
public RequiresCondition(AnnotationMetadata annotationMetadata) {
this.annotationMetadata = annotationMetadata;
}
@Override
public boolean matches(ConditionContext context) {
List> requirements = annotationMetadata.getAnnotationValuesByType(Requires.class);
if (requirements.isEmpty()) {
return true;
}
AnnotationMetadataProvider component = context.getComponent();
boolean isBeanReference = component instanceof BeanDefinitionReference;
if (component instanceof AbstractInitializableBeanDefinitionAndReference>) {
for (AnnotationValue requirement : requirements) {
if (!processPreStartRequirements(context, requirement)) {
return false;
}
if (!processPostStartRequirements(context, requirement)) {
return false;
}
}
return true;
}
// here we use AnnotationMetadata to avoid loading the classes referenced in the annotations directly
if (isBeanReference) {
for (AnnotationValue requirement : requirements) {
// if annotation value has evaluated expressions, postpone
// decision until the bean is loaded
if (requirement.hasEvaluatedExpressions()) {
continue;
}
if (!processPreStartRequirements(context, requirement)) {
return false;
}
}
} else {
for (AnnotationValue requires : requirements) {
if (!processPostStartRequirements(context, requires)) {
return false;
}
}
}
return true;
}
/**
* This method will process requirements for a {@link BeanDefinitionReference} that has not yet been loaded. Unlike {@link #processPostStartRequirements(ConditionContext, AnnotationValue)}
* this method is executed prior to the bean being loaded and processes requirements that do not require all the beans to be loaded.
*/
private boolean processPreStartRequirements(ConditionContext context, AnnotationValue requirements) {
List preConditions = new ArrayList<>(5);
List postConditions = new ArrayList<>(5);
MatchesConditionUtils.createConditions(requirements, preConditions, postConditions);
for (Condition condition : preConditions) {
if (!condition.matches(context)) {
return false;
}
}
return true;
}
/**
* This method will run conditions that require all beans to be loaded. These conditions included "beans", "bean", "missingBeans" and custom conditions.
*/
private boolean processPostStartRequirements(ConditionContext context, AnnotationValue requirements) {
List conditions = new ArrayList<>(10);
MatchesConditionUtils.createConditions(requirements, conditions, conditions);
for (Condition condition : conditions) {
if (!condition.matches(context)) {
return false;
}
}
return true;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy