• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

TAKETODAY / today-infrastructure / 18154768944

01 Oct 2025 07:26AM UTC coverage: 81.882% (-0.005%) from 81.887%
18154768944

push

github

web-flow
Merge pull request #290 from TAKETODAY/dev/jspecify

jspecify

59788 of 78013 branches covered (76.64%)

Branch coverage included in aggregate %.

141239 of 167496 relevant lines covered (84.32%)

3.6 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.69
today-context/src/main/java/infra/context/condition/FilteringInfraCondition.java
1
/*
2
 * Copyright 2017 - 2025 the original author or authors.
3
 *
4
 * This program is free software: you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation, either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program. If not, see [https://www.gnu.org/licenses/]
16
 */
17

18
package infra.context.condition;
19

20
import org.jspecify.annotations.Nullable;
21

22
import java.util.ArrayList;
23
import java.util.Collection;
24
import java.util.Collections;
25
import java.util.List;
26

27
import infra.beans.BeansException;
28
import infra.beans.factory.BeanClassLoaderAware;
29
import infra.beans.factory.BeanFactory;
30
import infra.beans.factory.BeanFactoryAware;
31
import infra.context.annotation.config.AutoConfigurationImportFilter;
32
import infra.context.annotation.config.AutoConfigurationMetadata;
33
import infra.util.ClassUtils;
34
import infra.util.CollectionUtils;
35

36
/**
37
 * Abstract base class for a {@link InfraCondition} that also implements
38
 * {@link AutoConfigurationImportFilter}.
39
 *
40
 * @author Phillip Webb
41
 * @author <a href="https://github.com/TAKETODAY">Harry Yang</a>
42
 * @since 4.0 2022/1/16 16:07
43
 */
44
public abstract class FilteringInfraCondition extends InfraCondition
3✔
45
        implements AutoConfigurationImportFilter, BeanFactoryAware, BeanClassLoaderAware {
46

47
  @SuppressWarnings("NullAway.Init")
48
  private BeanFactory beanFactory;
49

50
  @SuppressWarnings("NullAway.Init")
51
  private ClassLoader beanClassLoader;
52

53
  @Override
54
  public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
55
    this.beanFactory = beanFactory;
3✔
56
  }
1✔
57

58
  protected final BeanFactory getBeanFactory() {
59
    return this.beanFactory;
×
60
  }
61

62
  protected final ClassLoader getBeanClassLoader() {
63
    return this.beanClassLoader;
3✔
64
  }
65

66
  @Override
67
  public void setBeanClassLoader(ClassLoader classLoader) {
68
    this.beanClassLoader = classLoader;
3✔
69
  }
1✔
70

71
  @Override
72
  public boolean[] match(String[] autoConfigurationClasses, AutoConfigurationMetadata configMetadata) {
73
    ConditionEvaluationReport report = ConditionEvaluationReport.find(this.beanFactory);
4✔
74
    @Nullable ConditionOutcome[] outcomes = getOutcomes(autoConfigurationClasses, configMetadata);
5✔
75
    boolean[] match = new boolean[outcomes.length];
4✔
76
    for (int i = 0; i < outcomes.length; i++) {
8✔
77
      ConditionOutcome outcome = outcomes[i];
4✔
78
      match[i] = (outcome == null || outcome.isMatch());
11!
79
      if (!match[i] && outcome != null) {
6!
80
        String autoConfigurationClass = autoConfigurationClasses[i];
4✔
81
        logOutcome(autoConfigurationClass, outcome);
4✔
82
        if (report != null) {
2!
83
          report.recordConditionEvaluation(autoConfigurationClass, this, outcome);
5✔
84
        }
85
      }
86
    }
87
    return match;
2✔
88
  }
89

90
  protected abstract @Nullable ConditionOutcome[] getOutcomes(String[] configClasses, AutoConfigurationMetadata configMetadata);
91

92
  protected final List<String> filter(@Nullable Collection<String> classNames, ClassNameFilter classNameFilter, @Nullable ClassLoader classLoader) {
93
    if (CollectionUtils.isEmpty(classNames)) {
3✔
94
      return Collections.emptyList();
2✔
95
    }
96
    ArrayList<String> matches = new ArrayList<>(classNames.size());
6✔
97
    for (String candidate : classNames) {
10✔
98
      if (classNameFilter.matches(candidate, classLoader)) {
5✔
99
        matches.add(candidate);
4✔
100
      }
101
    }
1✔
102
    return matches;
2✔
103
  }
104

105
  /**
106
   * Slightly faster variant of {@link ClassUtils#forName(String, ClassLoader)} that
107
   * doesn't deal with primitives, arrays or inner types.
108
   *
109
   * @param className the class name to resolve
110
   * @param classLoader the class loader to use
111
   * @return a resolved class
112
   * @throws ClassNotFoundException if the class cannot be found
113
   */
114
  protected static Class<?> resolve(String className, @Nullable ClassLoader classLoader) throws ClassNotFoundException {
115
    if (classLoader != null) {
2!
116
      return Class.forName(className, false, classLoader);
5✔
117
    }
118
    return Class.forName(className);
×
119
  }
120

121
  protected enum ClassNameFilter {
3✔
122

123
    PRESENT {
11✔
124
      @Override
125
      public boolean matches(String className, @Nullable ClassLoader classLoader) {
126
        return isPresent(className, classLoader);
4✔
127
      }
128

129
    },
130

131
    MISSING {
11✔
132
      @Override
133
      public boolean matches(String className, @Nullable ClassLoader classLoader) {
134
        return !isPresent(className, classLoader);
8✔
135
      }
136

137
    };
138

139
    public abstract boolean matches(String className, @Nullable ClassLoader classLoader);
140

141
    private static boolean isPresent(String className, @Nullable ClassLoader classLoader) {
142
      if (classLoader == null) {
2!
143
        classLoader = ClassUtils.getDefaultClassLoader();
×
144
      }
145
      try {
146
        resolve(className, classLoader);
4✔
147
        return true;
2✔
148
      }
149
      catch (Throwable ex) {
1✔
150
        return false;
2✔
151
      }
152
    }
153

154
  }
155
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc