Skip to content

Commit f254653

Browse files
copy assets to temporary directory on instantiation of CodeCoverageReporter
1 parent 89666ff commit f254653

File tree

1 file changed

+74
-9
lines changed

1 file changed

+74
-9
lines changed

sqldev/src/main/java/org/utplsql/sqldev/coverage/CodeCoverageReporter.java

Lines changed: 74 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,25 @@
1717

1818
import java.awt.Desktop;
1919
import java.io.File;
20+
import java.io.IOException;
21+
import java.io.InputStream;
22+
import java.net.MalformedURLException;
2023
import java.net.URL;
2124
import java.nio.charset.StandardCharsets;
25+
import java.nio.file.Files;
26+
import java.nio.file.Path;
27+
import java.nio.file.Paths;
28+
import java.nio.file.StandardCopyOption;
2229
import java.sql.Connection;
23-
import java.util.ArrayList;
24-
import java.util.Arrays;
25-
import java.util.HashMap;
26-
import java.util.List;
27-
import java.util.Map;
30+
import java.util.*;
31+
import java.util.jar.JarEntry;
32+
import java.util.jar.JarFile;
2833
import java.util.logging.Logger;
2934
import java.util.stream.Collectors;
3035

36+
import org.springframework.core.io.Resource;
37+
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
38+
import org.springframework.core.io.support.ResourcePatternResolver;
3139
import org.utplsql.sqldev.dal.RealtimeReporterDao;
3240
import org.utplsql.sqldev.dal.UtplsqlDao;
3341
import org.utplsql.sqldev.exception.GenericDatabaseAccessException;
@@ -42,22 +50,25 @@
4250

4351
public class CodeCoverageReporter {
4452
private static final Logger logger = Logger.getLogger(CodeCoverageReporter.class.getName());
53+
private static final String ASSETS_PATH = "coverage/assets/";
4554

4655
private String connectionName;
4756
private Connection conn;
48-
private List<String> pathList;
49-
private List<String> includeObjectList;
57+
private final List<String> pathList;
58+
private final List<String> includeObjectList;
5059
private CodeCoverageReporterDialog frame;
5160
private String schemas;
5261
private String includeObjects;
5362
private String excludeObjects;
63+
private Path assetDir;
5464

5565
public CodeCoverageReporter(final List<String> pathList, final List<String> includeObjectList,
5666
final String connectionName) {
5767
this.pathList = pathList;
5868
this.includeObjectList = includeObjectList;
5969
setDefaultSchema();
6070
setConnection(connectionName);
71+
setAssetDir();
6172
}
6273

6374
// constructor for testing purposes only
@@ -67,6 +78,7 @@ public CodeCoverageReporter(final List<String> pathList, final List<String> incl
6778
this.includeObjectList = includeObjectList;
6879
this.conn = conn;
6980
setDefaultSchema();
81+
setAssetDir();
7082
}
7183

7284
private void setConnection(final String connectionName) {
@@ -105,6 +117,59 @@ private void setDefaultSchema() {
105117
}
106118
}
107119

120+
private void setAssetDir() {
121+
try {
122+
assetDir = Files.createTempDirectory("utplsql_assets_");
123+
} catch (IOException e) {
124+
throw new GenericRuntimeException("Cannot create temporary directory for code coverage report assets.", e);
125+
}
126+
populateCoverageAssets();
127+
}
128+
129+
// public for testing purposes only
130+
public URL getHtmlReportAssetPath() {
131+
try {
132+
return Paths.get(assetDir.toString()).toUri().toURL();
133+
} catch (MalformedURLException e) {
134+
throw new GenericRuntimeException("Cannot convert code coverage asset path to URL.", e);
135+
}
136+
}
137+
138+
private void copyStreamToFile(InputStream inputStream, Path file) throws IOException {
139+
file.toFile().mkdirs();
140+
Files.copy(inputStream, file, StandardCopyOption.REPLACE_EXISTING);
141+
}
142+
143+
private void populateCoverageAssets() {
144+
logger.fine(() -> "Copying code coverage report assets to " + assetDir.toString() + "...");
145+
try {
146+
final File file = new File(getClass().getProtectionDomain().getCodeSource().getLocation().getPath());
147+
if (file.isFile()) {
148+
// class loaded from a JAR file
149+
final JarFile jar = new JarFile(file);
150+
final List<JarEntry> entries = jar.stream().filter(entry -> !entry.isDirectory() && entry.getName().startsWith(ASSETS_PATH)).collect(Collectors.toList());
151+
for (JarEntry entry : entries) {
152+
Path f = Paths.get(assetDir.toString() + File.separator + entry.getName().substring(ASSETS_PATH.length()));
153+
copyStreamToFile(jar.getInputStream(entry), f);
154+
}
155+
} else {
156+
// class loaded from file system (IDE or during test/build)
157+
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
158+
Resource[] resources = resolver.getResources(ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + "/" + ASSETS_PATH + "**");
159+
for (Resource resource : resources) {
160+
if (Objects.requireNonNull(resource.getFilename()).contains(".")) {
161+
// process files but not directories, assume that directories do not contain a period
162+
String path = resource.getURL().getPath();
163+
Path f = Paths.get(assetDir.toString() + File.separator + path.substring(path.lastIndexOf(ASSETS_PATH) + ASSETS_PATH.length()));
164+
copyStreamToFile(resource.getInputStream(), f);
165+
}
166+
}
167+
}
168+
} catch (IOException e) {
169+
throw new GenericRuntimeException("Error while copying coverage report assets to temporary directory.", e);
170+
}
171+
}
172+
108173
private ArrayList<String> toStringList(final String s) {
109174
final ArrayList<String> list = new ArrayList<>();
110175
if (s != null && !s.isEmpty()) {
@@ -142,7 +207,7 @@ private void run() {
142207

143208
private void runCodeCoverageWithRealtimeReporter() {
144209
final UtplsqlRunner runner = new UtplsqlRunner(pathList, toStringList(schemas), toStringList(includeObjects),
145-
toStringList(excludeObjects), connectionName);
210+
toStringList(excludeObjects), getHtmlReportAssetPath(), connectionName);
146211
runner.runTestAsync();
147212
}
148213

@@ -152,7 +217,7 @@ private void runCodeCoverageStandalone() {
152217
coverageConn = conn != null ? conn : DatabaseTools.cloneConnection(connectionName);
153218
final UtplsqlDao dao = new UtplsqlDao(coverageConn);
154219
final String html = dao.htmlCodeCoverage(pathList, toStringList(schemas),
155-
toStringList(includeObjects), toStringList(excludeObjects));
220+
toStringList(includeObjects), toStringList(excludeObjects), getHtmlReportAssetPath());
156221
openInBrowser(html);
157222
} finally {
158223
try {

0 commit comments

Comments
 (0)