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

mybatis / thymeleaf-scripting / #1164

pending completion
#1164

Pull #189

github

web-flow
Merge e930cb29c into 34bbfca66
Pull Request #189: Update dependency org.mybatis:mybatis-parent to v38

611 of 621 relevant lines covered (98.39%)

0.98 hits per line

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

97.74
/src/main/java/org/mybatis/scripting/thymeleaf/SqlGeneratorConfig.java
1
/*
2
 *    Copyright 2018-2022 the original author or authors.
3
 *
4
 *    Licensed under the Apache License, Version 2.0 (the "License");
5
 *    you may not use this file except in compliance with the License.
6
 *    You may obtain a copy of the License at
7
 *
8
 *       https://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 *    Unless required by applicable law or agreed to in writing, software
11
 *    distributed under the License is distributed on an "AS IS" BASIS,
12
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 *    See the License for the specific language governing permissions and
14
 *    limitations under the License.
15
 */
16
package org.mybatis.scripting.thymeleaf;
17

18
import java.io.BufferedReader;
19
import java.io.IOException;
20
import java.io.InputStreamReader;
21
import java.lang.reflect.InvocationTargetException;
22
import java.nio.charset.Charset;
23
import java.nio.charset.StandardCharsets;
24
import java.util.Arrays;
25
import java.util.Collections;
26
import java.util.HashMap;
27
import java.util.Map;
28
import java.util.Optional;
29
import java.util.Properties;
30
import java.util.function.Consumer;
31
import java.util.function.Function;
32
import java.util.stream.Stream;
33

34
import org.mybatis.scripting.thymeleaf.PropertyAccessor.BuiltIn.StandardPropertyAccessor;
35
import org.mybatis.scripting.thymeleaf.processor.BindVariableRender;
36
import org.thymeleaf.util.ClassLoaderUtils;
37
import org.thymeleaf.util.StringUtils;
38

39
/**
40
 * Configuration class for {@link SqlGenerator}.
41
 *
42
 * @author Kazuki Shimizu
43
 *
44
 * @since 1.0.2
45
 */
46
public class SqlGeneratorConfig {
1✔
47

48
  private static class PropertyKeys {
49
    private static final String CONFIG_FILE = "mybatis-thymeleaf.config.file";
50
    private static final String CONFIG_ENCODING = "mybatis-thymeleaf.config.encoding";
51
  }
52

53
  private static class Defaults {
54
    private static final String PROPERTIES_FILE = "mybatis-thymeleaf.properties";
55
  }
56

57
  private static final Map<Class<?>, Function<String, Object>> TYPE_CONVERTERS;
58

59
  static {
60
    Map<Class<?>, Function<String, Object>> converters = new HashMap<>();
1✔
61
    converters.put(boolean.class, v -> Boolean.valueOf(v.trim()));
1✔
62
    converters.put(String.class, String::trim);
1✔
63
    converters.put(Character[].class, v -> Stream.of(v.split(",")).map(String::trim).filter(e -> e.length() == 1)
1✔
64
        .map(e -> e.charAt(0)).toArray(Character[]::new));
1✔
65
    converters.put(Character.class, v -> v.trim().charAt(0));
1✔
66
    converters.put(Charset.class, v -> Charset.forName(v.trim()));
1✔
67
    converters.put(Long.class, v -> Long.valueOf(v.trim()));
1✔
68
    converters.put(String[].class, v -> Stream.of(v.split(",")).map(String::trim).toArray(String[]::new));
1✔
69
    converters.put(Class.class, SqlGeneratorConfig::toClassForName);
1✔
70
    TYPE_CONVERTERS = Collections.unmodifiableMap(converters);
1✔
71
  }
1✔
72

73
  /**
74
   * Whether use the 2-way SQL feature.
75
   */
76
  private boolean use2way = true;
1✔
77

78
  /**
79
   * The instance for customizing a default TemplateEngine instanced by the mybatis-thymeleaf.
80
   */
81
  private TemplateEngineCustomizer customizer;
82

83
  /**
84
   * Template file configuration.
85
   */
86
  private final TemplateFileConfig templateFile = new TemplateFileConfig();
1✔
87

88
  /**
89
   * Dialect configuration.
90
   */
91
  private final DialectConfig dialect = new DialectConfig();
1✔
92

93
  /**
94
   * Get whether use the 2-way SQL feature.
95
   * <p>
96
   * Default is {@code true}.
97
   * </p>
98
   *
99
   * @return If use the 2-way SQL feature, return {@code true}
100
   */
101
  public boolean isUse2way() {
102
    return use2way;
1✔
103
  }
104

105
  /**
106
   * Set whether use the 2-way SQL feature.
107
   *
108
   * @param use2way
109
   *          If use the 2-way SQL feature, set {@code true}
110
   */
111
  public void setUse2way(boolean use2way) {
112
    this.use2way = use2way;
1✔
113
  }
1✔
114

115
  /**
116
   * Get the interface for customizing a default TemplateEngine instanced by the mybatis-thymeleaf.
117
   * <p>
118
   * Default is {@code null}.
119
   * </p>
120
   * This method exists for the backward compatibility.<br>
121
   * Use {@link #getCustomizerInstance()} instead
122
   *
123
   * @return the interface for customizing a default TemplateEngine
124
   */
125
  @Deprecated
126
  public Class<? extends TemplateEngineCustomizer> getCustomizer() {
127
    return customizer == null ? null : customizer.getClass();
×
128
  }
129

130
  /**
131
   * Set the interface for customizing a default TemplateEngine instanced by the mybatis-thymeleaf.
132
   *
133
   * @param customizer
134
   *          the interface for customizing a default TemplateEngine
135
   */
136
  @Deprecated
137
  public void setCustomizer(Class<? extends TemplateEngineCustomizer> customizer) {
138
    this.customizer = newInstanceForType(customizer);
1✔
139
  }
1✔
140

141
  public TemplateEngineCustomizer getCustomizerInstance() {
142
    return customizer;
1✔
143
  }
144

145
  public void setCustomizerInstance(TemplateEngineCustomizer customizer) {
146
    this.customizer = customizer;
1✔
147
  }
1✔
148

149
  /**
150
   * Get a template file configuration.
151
   *
152
   * @return a template file configuration
153
   */
154
  public TemplateFileConfig getTemplateFile() {
155
    return templateFile;
1✔
156
  }
157

158
  /**
159
   * Get a dialect configuration.
160
   *
161
   * @return a dialect configuration
162
   */
163
  public DialectConfig getDialect() {
164
    return dialect;
1✔
165
  }
166

167
  /**
168
   * Template file configuration.
169
   *
170
   * @since 1.0.0
171
   */
172
  public static class TemplateFileConfig {
1✔
173

174
    /**
175
     * The character encoding for reading template resource file.
176
     */
177
    private Charset encoding = StandardCharsets.UTF_8;
1✔
178

179
    /**
180
     * The base directory for reading template resource file.
181
     */
182
    private String baseDir = "";
1✔
183

184
    /**
185
     * The patterns for reading as template resource file. (Can specify multiple patterns using comma(",") as separator
186
     * character)
187
     */
188
    private String[] patterns = { "*.sql" };
1✔
189

190
    /**
191
     * Whether use the cache feature when load template resource file.
192
     */
193
    private boolean cacheEnabled = true;
1✔
194

195
    /**
196
     * The cache TTL(millisecond) for resolved templates.
197
     */
198
    private Long cacheTtl;
199

200
    /**
201
     * Get the character encoding for reading template resource file.
202
     * <p>
203
     * Default is {@code UTF-8}.
204
     * </p>
205
     *
206
     * @return the character encoding for reading template resource file
207
     */
208
    public Charset getEncoding() {
209
      return encoding;
1✔
210
    }
211

212
    /**
213
     * Set the character encoding for reading template resource file.
214
     *
215
     * @param encoding
216
     *          the character encoding for reading template resource file
217
     */
218
    public void setEncoding(Charset encoding) {
219
      this.encoding = encoding;
1✔
220
    }
1✔
221

222
    /**
223
     * Get the base directory for reading template resource file.
224
     * <p>
225
     * Default is {@code ""}(none).
226
     * </p>
227
     *
228
     * @return the base directory for reading template resource file
229
     */
230
    public String getBaseDir() {
231
      return baseDir;
1✔
232
    }
233

234
    /**
235
     * Set the base directory for reading template resource file.
236
     *
237
     * @param baseDir
238
     *          the base directory for reading template resource file
239
     */
240
    public void setBaseDir(String baseDir) {
241
      this.baseDir = baseDir;
1✔
242
    }
1✔
243

244
    /**
245
     * Get patterns for reading as template resource file.
246
     * <p>
247
     * Default is {@code "*.sql"}.
248
     * </p>
249
     *
250
     * @return patterns for reading as template resource file
251
     */
252
    public String[] getPatterns() {
253
      return patterns;
1✔
254
    }
255

256
    /**
257
     * Set patterns for reading as template resource file.
258
     *
259
     * @param patterns
260
     *          patterns for reading as template resource file
261
     */
262
    public void setPatterns(String... patterns) {
263
      this.patterns = patterns;
1✔
264
    }
1✔
265

266
    /**
267
     * Get whether use the cache feature when load template resource file.
268
     * <p>
269
     * Default is {@code true}.
270
     * </p>
271
     *
272
     * @return If use th cache feature, return {@code true}
273
     */
274
    public boolean isCacheEnabled() {
275
      return cacheEnabled;
1✔
276
    }
277

278
    /**
279
     * Set whether use the cache feature when load template resource file.
280
     *
281
     * @param cacheEnabled
282
     *          If use th cache feature, set {@code true}
283
     */
284
    public void setCacheEnabled(boolean cacheEnabled) {
285
      this.cacheEnabled = cacheEnabled;
1✔
286
    }
1✔
287

288
    /**
289
     * Get the cache TTL(millisecond) for resolved templates.
290
     * <p>
291
     * Default is {@code null}(indicate to use default value of Thymeleaf).
292
     * </p>
293
     *
294
     * @return the cache TTL(millisecond) for resolved templates
295
     */
296
    public Long getCacheTtl() {
297
      return cacheTtl;
1✔
298
    }
299

300
    /**
301
     * Set the cache TTL(millisecond) for resolved templates.
302
     *
303
     * @param cacheTtl
304
     *          the cache TTL(millisecond) for resolved templates
305
     */
306
    public void setCacheTtl(Long cacheTtl) {
307
      this.cacheTtl = cacheTtl;
1✔
308
    }
1✔
309

310
  }
311

312
  /**
313
   * Dialect configuration.
314
   *
315
   * @since 1.0.0
316
   */
317
  public static class DialectConfig {
1✔
318

319
    /**
320
     * The prefix name of dialect provided by this project.
321
     */
322
    private String prefix = "mb";
1✔
323

324
    /**
325
     * The escape character for wildcard of LIKE condition.
326
     */
327
    private Character likeEscapeChar = '\\';
1✔
328

329
    /**
330
     * The format of escape clause for LIKE condition (Can specify format that can be allowed by String#format method).
331
     */
332
    private String likeEscapeClauseFormat = "ESCAPE '%s'";
1✔
333

334
    /**
335
     * Additional escape target characters(custom wildcard characters) for LIKE condition. (Can specify multiple
336
     * characters using comma(",") as separator character)
337
     */
338
    private Character[] likeAdditionalEscapeTargetChars;
339

340
    /**
341
     * The bind variable render.
342
     */
343
    private BindVariableRender bindVariableRender;
344

345
    /**
346
     * Get the prefix name of dialect provided by this project.
347
     * <p>
348
     * Default is {@code "mb"}.
349
     * </p>
350
     *
351
     * @return the prefix name of dialect
352
     */
353
    public String getPrefix() {
354
      return prefix;
1✔
355
    }
356

357
    /**
358
     * Set the prefix name of dialect provided by this project.
359
     *
360
     * @param prefix
361
     *          the prefix name of dialect
362
     */
363
    public void setPrefix(String prefix) {
364
      this.prefix = prefix;
1✔
365
    }
1✔
366

367
    /**
368
     * Get the escape character for wildcard of LIKE condition.
369
     * <p>
370
     * Default is {@code '\'}.
371
     * </p>
372
     *
373
     * @return the escape character for wildcard
374
     */
375
    public Character getLikeEscapeChar() {
376
      return likeEscapeChar;
1✔
377
    }
378

379
    /**
380
     * Set the escape character for wildcard of LIKE condition.
381
     *
382
     * @param likeEscapeChar
383
     *          the escape character for wildcard
384
     */
385
    public void setLikeEscapeChar(Character likeEscapeChar) {
386
      this.likeEscapeChar = likeEscapeChar;
1✔
387
    }
1✔
388

389
    /**
390
     * Get the format of escape clause for LIKE condition.
391
     * <p>
392
     * Can specify format that can be allowed by String#format method. Default is {@code "ESCAPE '%s'"}.
393
     * </p>
394
     *
395
     * @return the format of escape clause for LIKE condition
396
     */
397
    public String getLikeEscapeClauseFormat() {
398
      return likeEscapeClauseFormat;
1✔
399
    }
400

401
    /**
402
     * Set the format of escape clause for LIKE condition.
403
     *
404
     * @param likeEscapeClauseFormat
405
     *          the format of escape clause for LIKE condition
406
     */
407
    public void setLikeEscapeClauseFormat(String likeEscapeClauseFormat) {
408
      this.likeEscapeClauseFormat = likeEscapeClauseFormat;
1✔
409
    }
1✔
410

411
    /**
412
     * Get additional escape target characters(custom wildcard characters) for LIKE condition.
413
     * <p>
414
     * Can specify multiple characters using comma(",") as separator character. Default is empty(none).
415
     * </p>
416
     *
417
     * @return additional escape target characters(custom wildcard characters)
418
     */
419
    public Character[] getLikeAdditionalEscapeTargetChars() {
420
      return likeAdditionalEscapeTargetChars;
1✔
421
    }
422

423
    /**
424
     * Set additional escape target characters(custom wildcard characters) for LIKE condition.
425
     *
426
     * @param likeAdditionalEscapeTargetChars
427
     *          additional escape target characters(custom wildcard characters)
428
     */
429
    public void setLikeAdditionalEscapeTargetChars(Character... likeAdditionalEscapeTargetChars) {
430
      this.likeAdditionalEscapeTargetChars = likeAdditionalEscapeTargetChars;
1✔
431
    }
1✔
432

433
    /**
434
     * Get a bind variable render.
435
     * <p>
436
     * Default is {@link BindVariableRender.BuiltIn#MYBATIS}
437
     * </p>
438
     * This method exists for the backward compatibility. <br>
439
     * Use {@link #getBindVariableRenderInstance()} instead
440
     *
441
     * @return a bind variable render
442
     */
443
    @Deprecated
444
    public Class<? extends BindVariableRender> getBindVariableRender() {
445
      return bindVariableRender == null ? null : bindVariableRender.getClass();
1✔
446
    }
447

448
    /**
449
     * This method exists for the backward compatibility.<br>
450
     * Use {@link #setBindVariableRenderInstance(BindVariableRender)} instead
451
     *
452
     * @param bindVariableRender
453
     *          bindVariableRender class
454
     */
455
    @Deprecated
456
    public void setBindVariableRender(Class<? extends BindVariableRender> bindVariableRender) {
457
      this.bindVariableRender = newInstanceForType(bindVariableRender);
1✔
458
    }
1✔
459

460
    public BindVariableRender getBindVariableRenderInstance() {
461
      return bindVariableRender;
1✔
462
    }
463

464
    public void setBindVariableRenderInstance(BindVariableRender bindVariableRender) {
465
      this.bindVariableRender = bindVariableRender;
1✔
466
    }
1✔
467
  }
468

469
  /**
470
   * Create an instance from default properties file. <br>
471
   * If you want to customize a default {@code TemplateEngine}, you can configure some property using
472
   * mybatis-thymeleaf.properties that encoded by UTF-8. Also, you can change the properties file that will read using
473
   * system property (-Dmybatis-thymeleaf.config.file=... -Dmybatis-thymeleaf.config.encoding=...). <br>
474
   * Supported properties are as follows:
475
   * <table border="1">
476
   * <caption>Supported properties</caption>
477
   * <tr>
478
   * <th>Property Key</th>
479
   * <th>Description</th>
480
   * <th>Default</th>
481
   * </tr>
482
   * <tr>
483
   * <th colspan="3">General configuration</th>
484
   * </tr>
485
   * <tr>
486
   * <td>use2way</td>
487
   * <td>Whether use the 2-way SQL</td>
488
   * <td>{@code true}</td>
489
   * </tr>
490
   * <tr>
491
   * <td>customizer</td>
492
   * <td>The implementation class for customizing a default {@code TemplateEngine} instanced by the MyBatis Thymeleaf
493
   * </td>
494
   * <td>None</td>
495
   * </tr>
496
   * <tr>
497
   * <th colspan="3">Template file configuration</th>
498
   * </tr>
499
   * <tr>
500
   * <td>template-file.cache-enabled</td>
501
   * <td>Whether use the cache feature</td>
502
   * <td>{@code true}</td>
503
   * </tr>
504
   * <tr>
505
   * <td>template-file.cache-ttl</td>
506
   * <td>The cache TTL for resolved templates</td>
507
   * <td>None(use default value of Thymeleaf)</td>
508
   * </tr>
509
   * <tr>
510
   * <td>template-file.encoding</td>
511
   * <td>The character encoding for reading template resources</td>
512
   * <td>{@code "UTF-8"}</td>
513
   * </tr>
514
   * <tr>
515
   * <td>template-file.base-dir</td>
516
   * <td>The base directory for reading template resources</td>
517
   * <td>None(just under class path)</td>
518
   * </tr>
519
   * <tr>
520
   * <td>template-file.patterns</td>
521
   * <td>The patterns for reading as template resources</td>
522
   * <td>{@code "*.sql"}</td>
523
   * </tr>
524
   * <tr>
525
   * <th colspan="3">Dialect configuration</th>
526
   * </tr>
527
   * <tr>
528
   * <td>dialect.prefix</td>
529
   * <td>The prefix name of dialect provided by this project</td>
530
   * <td>{@code "mb"}</td>
531
   * </tr>
532
   * <tr>
533
   * <td>dialect.like-escape-char</td>
534
   * <td>The escape character for wildcard of LIKE</td>
535
   * <td>{@code '\'} (backslash)</td>
536
   * </tr>
537
   * <tr>
538
   * <td>dialect.like-escape-clause-format</td>
539
   * <td>The format of escape clause</td>
540
   * <td>{@code "ESCAPE '%s'"}</td>
541
   * </tr>
542
   * <tr>
543
   * <td>dialect.like-additional-escape-target-chars</td>
544
   * <td>The additional escape target characters(custom wildcard characters) for LIKE condition</td>
545
   * <td>None</td>
546
   * </tr>
547
   * </table>
548
   *
549
   * @return a configuration instance
550
   */
551
  public static SqlGeneratorConfig newInstance() {
552
    SqlGeneratorConfig config = new SqlGeneratorConfig();
1✔
553
    applyDefaultProperties(config);
1✔
554
    return config;
1✔
555
  }
556

557
  /**
558
   * Create an instance from specified properties file. <br>
559
   * you can configure some property using specified properties file that encoded by UTF-8. Also, you can change file
560
   * encoding that will read using system property (-Dmybatis-thymeleaf.config.encoding=...).
561
   *
562
   * @param resourcePath
563
   *          A property file resource path
564
   *
565
   * @return a configuration instance
566
   *
567
   * @see #newInstance()
568
   */
569
  public static SqlGeneratorConfig newInstanceWithResourcePath(String resourcePath) {
570
    SqlGeneratorConfig config = new SqlGeneratorConfig();
1✔
571
    applyResourcePath(config, resourcePath);
1✔
572
    return config;
1✔
573
  }
574

575
  /**
576
   * Create an instance from specified properties.
577
   *
578
   * @param customProperties
579
   *          custom configuration properties
580
   *
581
   * @return a configuration instance
582
   *
583
   * @see #newInstance()
584
   */
585
  public static SqlGeneratorConfig newInstanceWithProperties(Properties customProperties) {
586
    SqlGeneratorConfig config = new SqlGeneratorConfig();
1✔
587
    applyProperties(config, customProperties);
1✔
588
    return config;
1✔
589
  }
590

591
  /**
592
   * Create an instance using specified customizer and override using a default properties file.
593
   *
594
   * @param customizer
595
   *          baseline customizer
596
   *
597
   * @return a configuration instance
598
   *
599
   * @see #newInstance()
600
   */
601
  public static SqlGeneratorConfig newInstanceWithCustomizer(Consumer<SqlGeneratorConfig> customizer) {
602
    SqlGeneratorConfig config = new SqlGeneratorConfig();
1✔
603
    customizer.accept(config);
1✔
604
    applyDefaultProperties(config);
1✔
605
    return config;
1✔
606
  }
607

608
  /**
609
   * Apply properties that read from default properties file. <br>
610
   * If you want to customize a default {@code TemplateEngine}, you can configure some property using
611
   * mybatis-thymeleaf.properties that encoded by UTF-8. Also, you can change the properties file that will read using
612
   * system property (-Dmybatis-thymeleaf.config.file=... -Dmybatis-thymeleaf.config.encoding=...).
613
   */
614
  static <T extends SqlGeneratorConfig> void applyDefaultProperties(T config) {
615
    applyProperties(config, loadDefaultProperties());
1✔
616
  }
1✔
617

618
  /**
619
   * Apply properties that read from specified properties file. <br>
620
   * you can configure some property using specified properties file that encoded by UTF-8. Also, you can change file
621
   * encoding that will read using system property (-Dmybatis-thymeleaf.config.encoding=...).
622
   *
623
   * @param resourcePath
624
   *          A property file resource path
625
   */
626
  static <T extends SqlGeneratorConfig> void applyResourcePath(T config, String resourcePath) {
627
    Properties properties = loadDefaultProperties();
1✔
628
    properties.putAll(loadProperties(resourcePath));
1✔
629
    applyProperties(config, properties);
1✔
630
  }
1✔
631

632
  /**
633
   * Apply properties from specified properties.
634
   *
635
   * @param config
636
   *          a configuration instance
637
   * @param customProperties
638
   *          custom configuration properties
639
   */
640
  static <T extends SqlGeneratorConfig> void applyProperties(T config, Properties customProperties) {
641
    Properties properties = loadDefaultProperties();
1✔
642
    Optional.ofNullable(customProperties).ifPresent(properties::putAll);
1✔
643
    override(config, properties);
1✔
644
  }
1✔
645

646
  /**
647
   * Create new instance using default constructor with specified type.
648
   *
649
   * @param type
650
   *          a target type
651
   * @param <T>
652
   *          a target type
653
   *
654
   * @return new instance of target type
655
   */
656
  static <T> T newInstanceForType(Class<T> type) {
657
    try {
658
      return type.getConstructor().newInstance();
1✔
659
    } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
1✔
660
      throw new IllegalStateException("Cannot create an instance for class: " + type, e);
1✔
661
    }
662
  }
663

664
  private static void override(SqlGeneratorConfig config, Properties properties) {
665
    PropertyAccessor standardPropertyAccessor = PropertyAccessor.BuiltIn.STANDARD;
1✔
666
    try {
667
      properties.forEach((key, value) -> {
1✔
668
        String propertyPath = StringUtils.unCapitalize(StringUtils.capitalizeWords(key, "-").replaceAll("-", ""));
1✔
669
        try {
670
          Object target = config;
1✔
671
          String propertyName;
672
          if (propertyPath.indexOf('.') != -1) {
1✔
673
            String[] propertyPaths = StringUtils.split(propertyPath, ".");
1✔
674
            propertyName = propertyPaths[propertyPaths.length - 1];
1✔
675
            for (String path : Arrays.copyOf(propertyPaths, propertyPaths.length - 1)) {
1✔
676
              target = standardPropertyAccessor.getPropertyValue(target, path);
1✔
677
            }
678
          } else {
1✔
679
            propertyName = propertyPath;
1✔
680
          }
681
          Object convertedValue = TYPE_CONVERTERS
1✔
682
              .getOrDefault(standardPropertyAccessor.getPropertyType(target.getClass(), propertyName), v -> v)
1✔
683
              .apply(value.toString());
1✔
684
          standardPropertyAccessor.setPropertyValue(target, propertyName, convertedValue);
1✔
685
        } catch (IllegalArgumentException e) {
1✔
686
          throw new IllegalArgumentException(
1✔
687
              String.format("Detected an invalid property. key='%s' value='%s'", key, value), e);
1✔
688
        }
1✔
689
      });
1✔
690
    } finally {
691
      StandardPropertyAccessor.clearCache();
1✔
692
    }
693
  }
1✔
694

695
  private static Properties loadDefaultProperties() {
696
    return loadProperties(System.getProperty(PropertyKeys.CONFIG_FILE, Defaults.PROPERTIES_FILE));
1✔
697
  }
698

699
  private static Properties loadProperties(String resourcePath) {
700
    Properties properties = new Properties();
1✔
701
    Optional.ofNullable(ClassLoaderUtils.findResourceAsStream(resourcePath)).ifPresent(in -> {
1✔
702
      Charset encoding = Optional.ofNullable(System.getProperty(PropertyKeys.CONFIG_ENCODING)).map(Charset::forName)
1✔
703
          .orElse(StandardCharsets.UTF_8);
1✔
704
      try (InputStreamReader inReader = new InputStreamReader(in, encoding);
1✔
705
          BufferedReader bufReader = new BufferedReader(inReader)) {
1✔
706
        properties.load(bufReader);
1✔
707
      } catch (IOException e) {
×
708
        throw new IllegalStateException(e);
×
709
      }
1✔
710
    });
1✔
711
    return properties;
1✔
712
  }
713

714
  private static Class<?> toClassForName(String value) {
715
    try {
716
      return ClassLoaderUtils.loadClass(value.trim());
1✔
717
    } catch (ClassNotFoundException e) {
1✔
718
      throw new IllegalStateException(e);
1✔
719
    }
720
  }
721

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

© 2025 Coveralls, Inc