• 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

64.86
today-context/src/main/java/infra/scripting/support/ResourceScriptSource.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.scripting.support;
19

20
import org.jspecify.annotations.Nullable;
21

22
import java.io.IOException;
23
import java.io.Reader;
24
import java.nio.charset.StandardCharsets;
25

26
import infra.core.io.EncodedResource;
27
import infra.core.io.Resource;
28
import infra.core.io.ResourceLoader;
29
import infra.lang.Assert;
30
import infra.logging.Logger;
31
import infra.logging.LoggerFactory;
32
import infra.scripting.ScriptSource;
33
import infra.util.FileCopyUtils;
34
import infra.util.StringUtils;
35

36
/**
37
 * {@link ScriptSource} implementation
38
 * based on Framework's {@link Resource}
39
 * abstraction. Loads the script text from the underlying Resource's
40
 * {@link Resource#getFile() File} or
41
 * {@link Resource#getInputStream() InputStream},
42
 * and tracks the last-modified timestamp of the file (if possible).
43
 *
44
 * @author Rob Harrop
45
 * @author Juergen Hoeller
46
 * @author <a href="https://github.com/TAKETODAY">海子 Yang</a>
47
 * @see Resource#getInputStream()
48
 * @see Resource#getFile()
49
 * @see ResourceLoader
50
 * @since 4.0
51
 */
52
public class ResourceScriptSource implements ScriptSource {
53
  private static final Logger log = LoggerFactory.getLogger(ResourceScriptSource.class);
4✔
54

55
  private EncodedResource resource;
56

57
  private long lastModified = -1;
3✔
58

59
  private final Object lastModifiedMonitor = new Object();
5✔
60

61
  /**
62
   * Create a new ResourceScriptSource for the given resource.
63
   *
64
   * @param resource the EncodedResource to load the script from
65
   */
66
  public ResourceScriptSource(EncodedResource resource) {
×
67
    Assert.notNull(resource, "Resource is required");
×
68
    this.resource = resource;
×
69
  }
×
70

71
  /**
72
   * Create a new ResourceScriptSource for the given resource.
73
   *
74
   * @param resource the Resource to load the script from (using UTF-8 encoding)
75
   */
76
  public ResourceScriptSource(Resource resource) {
2✔
77
    Assert.notNull(resource, "Resource is required");
3✔
78
    this.resource = new EncodedResource(resource, StandardCharsets.UTF_8);
7✔
79
  }
1✔
80

81
  /**
82
   * Return the {@link Resource} to load the
83
   * script from.
84
   */
85
  public final Resource getResource() {
86
    return this.resource.getResource();
4✔
87
  }
88

89
  /**
90
   * Set the encoding used for reading the script resource.
91
   * <p>The default value for regular Resources is "UTF-8".
92
   * A {@code null} value implies the platform default.
93
   */
94
  public void setEncoding(@Nullable String encoding) {
95
    this.resource = new EncodedResource(this.resource.getResource(), encoding);
×
96
  }
×
97

98
  @Override
99
  public String getScriptAsString() throws IOException {
100
    synchronized(this.lastModifiedMonitor) {
5✔
101
      this.lastModified = retrieveLastModifiedTime();
4✔
102
    }
3✔
103
    Reader reader = this.resource.getReader();
4✔
104
    return FileCopyUtils.copyToString(reader);
3✔
105
  }
106

107
  @Override
108
  public boolean isModified() {
109
    synchronized(this.lastModifiedMonitor) {
5✔
110
      return (this.lastModified < 0 || retrieveLastModifiedTime() > this.lastModified);
17✔
111
    }
112
  }
113

114
  /**
115
   * Retrieve the current last-modified timestamp of the underlying resource.
116
   *
117
   * @return the current timestamp, or 0 if not determinable
118
   */
119
  protected long retrieveLastModifiedTime() {
120
    try {
121
      return getResource().lastModified();
4✔
122
    }
123
    catch (IOException ex) {
1✔
124
      if (log.isDebugEnabled()) {
3!
125
        log.debug(getResource() + " could not be resolved in the file system - " +
×
126
                "current timestamp not available for script modification check", ex);
127
      }
128
      return 0;
2✔
129
    }
130
  }
131

132
  @Override
133
  @Nullable
134
  public String suggestedClassName() {
135
    String filename = getResource().getName();
×
136
    return filename != null ? StringUtils.stripFilenameExtension(filename) : null;
×
137
  }
138

139
  @Override
140
  public String toString() {
141
    return this.resource.toString();
×
142
  }
143

144
}
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