Skip to content

Commit 9a70d24

Browse files
committed
First simple version of ReporterInspector working
1 parent 6648276 commit 9a70d24

File tree

8 files changed

+342
-34
lines changed

8 files changed

+342
-34
lines changed

src/main/java/org/utplsql/api/reporter/ReporterFactory.java

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,34 +6,37 @@
66
import oracle.sql.STRUCT;
77
import org.utplsql.api.compatibility.CompatibilityProxy;
88

9-
import java.sql.Connection;
109
import java.sql.SQLException;
11-
import java.util.Arrays;
1210
import java.util.HashMap;
1311
import java.util.Map;
1412
import java.util.function.BiFunction;
1513

1614
/** This class manages the instantiation of reporters.
1715
* One can register a supplier method for a specific name which will then be callable via createReporter(name)
1816
*
17+
* Use the static createEmpty or createDefault methods to get a new instance.
18+
* We don't allow direct instantiation because we want
19+
* <ul>
20+
* <li>Register default ReporterFactoryMethods for Core-Reporters</li>
21+
* <li>Be able to add more than one ReporterFactory implementation due to backwards-compatibility in future</li>
22+
* </ul>
23+
*
1924
* @author pesse
2025
*/
2126
public final class ReporterFactory implements ORADataFactory {
2227

23-
public static class ReporterInfo {
24-
public ReporterInfo(BiFunction<String, Object[], ? extends Reporter> factoryMethod, String description) {
28+
public static class ReporterFactoryMethodInfo {
29+
public ReporterFactoryMethodInfo(BiFunction<String, Object[], ? extends Reporter> factoryMethod, String description) {
2530
this.factoryMethod = factoryMethod;
2631
this.description = description;
2732
}
2833
public BiFunction<String, Object[], ? extends Reporter> factoryMethod;
2934
public String description;
3035
}
3136

32-
private Map<String, ReporterInfo> reportFactoryMethodMap = new HashMap<>();
33-
34-
ReporterFactory() {
37+
private Map<String, ReporterFactoryMethodInfo> reportFactoryMethodMap = new HashMap<>();
3538

36-
}
39+
ReporterFactory() { }
3740

3841
/** Registers a creation method for a specified reporter name. Overrides eventually existing creation method
3942
*
@@ -42,19 +45,28 @@ public ReporterInfo(BiFunction<String, Object[], ? extends Reporter> factoryMeth
4245
* @param description the description of the reporter
4346
* @return Object with information about the registered reporter
4447
*/
45-
public synchronized ReporterInfo registerReporterFactoryMethod( String reporterName, BiFunction<String, Object[], ? extends Reporter> factoryMethod, String description) {
46-
return reportFactoryMethodMap.put(reporterName.toUpperCase(), new ReporterInfo(factoryMethod, description));
48+
public synchronized ReporterFactoryMethodInfo registerReporterFactoryMethod(String reporterName, BiFunction<String, Object[], ? extends Reporter> factoryMethod, String description) {
49+
return reportFactoryMethodMap.put(reporterName.toUpperCase(), new ReporterFactoryMethodInfo(factoryMethod, description));
4750
}
4851

4952
/** Unregisters a specified reporter name.
5053
*
5154
* @param reporterName the reporter's name to unregister
5255
* @return information about the reporter which was previously registered or null
5356
*/
54-
public synchronized ReporterInfo unregisterReporterFactoryMethod( String reporterName ) {
57+
public synchronized ReporterFactoryMethodInfo unregisterReporterFactoryMethod(String reporterName ) {
5558
return reportFactoryMethodMap.remove(reporterName.toUpperCase());
5659
}
5760

61+
/** Checks whether a given reporter has a registered FactoryMethod or not
62+
*
63+
* @param reporterName the reporter's name
64+
* @return true or false
65+
*/
66+
public synchronized boolean hasRegisteredFactoryMethodFor( String reporterName ) {
67+
return reportFactoryMethodMap.containsKey(reporterName.toUpperCase());
68+
}
69+
5870
/** Returns a new reporter of the given name.
5971
* If no specific ReporterFactoryMethod is registered, returns a default {Reporter}
6072
*
@@ -69,9 +81,9 @@ public Reporter createReporter(String reporterName, Object[] attributes) {
6981

7082
if ( reportFactoryMethodMap.containsKey(reporterName)) {
7183

72-
ReporterInfo ri = reportFactoryMethodMap.get(reporterName);
84+
ReporterFactoryMethodInfo ri = reportFactoryMethodMap.get(reporterName);
7385
if (ri == null)
74-
throw new RuntimeException("ReporterInfo for " + reporterName + " was null");
86+
throw new RuntimeException("ReporterFactoryMethodInfo for " + reporterName + " was null");
7587

7688
supplier = ri.factoryMethod;
7789
}
@@ -89,23 +101,14 @@ public Reporter createReporter( String reporterName ) {
89101
return createReporter(reporterName, null);
90102
}
91103

92-
/** Returns a new reporter of the given DefaultReporter type
93-
*
94-
* @param reporter
95-
* @return
96-
*/
97-
public Reporter createReporter( CoreReporters reporter ) {
98-
return createReporter(reporter.name());
99-
}
100-
101104
/** Returns a set of all registered reporter's names
102105
*
103106
* @return Set of reporter names
104107
*/
105108
public Map<String, String> getRegisteredReporterInfo() {
106109
Map<String, String> descMap = new HashMap<>(reportFactoryMethodMap.size());
107110

108-
for (Map.Entry<String, ReporterInfo> entry : reportFactoryMethodMap.entrySet()) {
111+
for (Map.Entry<String, ReporterFactoryMethodInfo> entry : reportFactoryMethodMap.entrySet()) {
109112
descMap.put(entry.getKey(), entry.getValue().description);
110113
}
111114
return descMap;
@@ -132,7 +135,7 @@ public static ReporterFactory createEmpty() {
132135
}
133136

134137
/** Returns a new instance of a ReporterFactory with the default ReporterFactoryMethods registered.
135-
* This can depend upon the version of utPLSQL, therefore you have to provide a CompatibilityProxy
138+
* This can depend on the version of utPLSQL, therefore you have to provide a CompatibilityProxy
136139
*
137140
* @param proxy Compatibility proxy
138141
* @return a new ReporterFactory instance with all default ReporterFactoryMethods registered

src/main/java/org/utplsql/api/reporter/ReporterInspector.java

Lines changed: 0 additions & 10 deletions
This file was deleted.
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package org.utplsql.api.reporter.inspect;
2+
3+
import org.utplsql.api.reporter.ReporterFactory;
4+
5+
import java.sql.Connection;
6+
import java.sql.SQLException;
7+
import java.util.ArrayList;
8+
import java.util.List;
9+
import java.util.Map;
10+
import java.util.Set;
11+
import java.util.stream.Collectors;
12+
13+
abstract class AbstractReporterInspector implements ReporterInspector {
14+
15+
protected ReporterFactory reporterFactory;
16+
protected Connection connection;
17+
protected Set<ReporterInfo> infos;
18+
19+
AbstractReporterInspector(ReporterFactory reporterFactory, Connection conn ) throws SQLException {
20+
this.reporterFactory = reporterFactory;
21+
this.connection = conn;
22+
23+
load();
24+
}
25+
26+
protected abstract void load() throws SQLException;
27+
28+
@Override
29+
public Map<String, ReporterInfo> getReporterInfoMap() {
30+
return infos.stream().collect(Collectors.toMap(ReporterInfo::getName, i -> i));
31+
}
32+
33+
@Override
34+
public List<ReporterInfo> getReporterInfos() {
35+
return new ArrayList<>(infos);
36+
}
37+
38+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package org.utplsql.api.reporter.inspect;
2+
3+
/** Holds information about utPLSQL Reporter-Types
4+
*
5+
* @author pesse
6+
*/
7+
public class ReporterInfo {
8+
9+
public enum Type {
10+
SQL, JAVA, SQL_WITH_JAVA
11+
}
12+
13+
private String name;
14+
private Type type;
15+
private String description;
16+
17+
ReporterInfo( String name, Type type, String description ) {
18+
this.name = name;
19+
this.type = type;
20+
this.description = description;
21+
}
22+
23+
public String getName() {
24+
return name;
25+
}
26+
27+
public Type getType() {
28+
return type;
29+
}
30+
31+
public String getDescription() {
32+
return description;
33+
}
34+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package org.utplsql.api.reporter.inspect;
2+
3+
import org.utplsql.api.Version;
4+
import org.utplsql.api.compatibility.CompatibilityProxy;
5+
import org.utplsql.api.exception.InvalidVersionException;
6+
import org.utplsql.api.reporter.ReporterFactory;
7+
8+
import java.sql.Connection;
9+
import java.sql.SQLException;
10+
import java.util.List;
11+
import java.util.Map;
12+
13+
/**
14+
* Gives information about available reporters
15+
*
16+
* @author pesse
17+
*/
18+
public interface ReporterInspector {
19+
20+
List<ReporterInfo> getReporterInfos();
21+
22+
Map<String, ReporterInfo> getReporterInfoMap();
23+
24+
/**
25+
* Returns a new instance of a ReporterInspector, based on the utPLSQL version used in the connection
26+
*
27+
* @param reporterFactory
28+
* @param conn
29+
* @return
30+
* @throws SQLException
31+
*/
32+
static ReporterInspector create(ReporterFactory reporterFactory, Connection conn) throws SQLException, InvalidVersionException {
33+
34+
CompatibilityProxy proxy = new CompatibilityProxy(conn);
35+
36+
if (proxy.getDatabaseVersion().isGreaterOrEqualThan(new Version("3.1.0")))
37+
return new ReporterInspector310(reporterFactory, conn);
38+
else
39+
return new ReporterInspectorPre310(reporterFactory, conn);
40+
}
41+
42+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package org.utplsql.api.reporter.inspect;
2+
3+
import oracle.jdbc.OracleCallableStatement;
4+
import oracle.jdbc.OracleConnection;
5+
import oracle.jdbc.OracleType;
6+
import org.utplsql.api.compatibility.CompatibilityProxy;
7+
import org.utplsql.api.reporter.CoreReporters;
8+
import org.utplsql.api.reporter.Reporter;
9+
import org.utplsql.api.reporter.ReporterFactory;
10+
11+
import java.sql.Connection;
12+
import java.sql.PreparedStatement;
13+
import java.sql.ResultSet;
14+
import java.sql.SQLException;
15+
import java.util.*;
16+
import java.util.stream.Collectors;
17+
18+
/** ReporterInspector for v3.1.0 upwards
19+
*
20+
* @author pesse
21+
*/
22+
class ReporterInspector310 extends AbstractReporterInspector {
23+
24+
25+
private Map<String, String> registeredReporterFactoryMethods;
26+
private CompatibilityProxy compatibilityProxy;
27+
28+
ReporterInspector310(ReporterFactory reporterFactory, Connection conn ) throws SQLException {
29+
super(reporterFactory, conn);
30+
}
31+
32+
@Override
33+
protected void load() throws SQLException {
34+
35+
registeredReporterFactoryMethods = reporterFactory.getRegisteredReporterInfo();
36+
compatibilityProxy = new CompatibilityProxy(connection);
37+
38+
infos = new HashSet<>();
39+
40+
try (PreparedStatement stmt = connection.prepareStatement("select * from table(ut_runner.get_reporters_list) order by 1")) {
41+
try (ResultSet rs = stmt.executeQuery() ) {
42+
while (rs.next())
43+
infos.add(getReporterInfo(rs.getString(1)));
44+
}
45+
}
46+
}
47+
48+
private ReporterInfo getReporterInfo( String reporterNameWithOwner ) throws SQLException {
49+
String reporterName = reporterNameWithOwner.substring(reporterNameWithOwner.indexOf(".")+1).toUpperCase();
50+
51+
ReporterInfo.Type type = ReporterInfo.Type.SQL;
52+
String description = getDescription(reporterName);
53+
54+
if ( registeredReporterFactoryMethods.containsKey(reporterName) ) {
55+
type = ReporterInfo.Type.SQL_WITH_JAVA;
56+
description += "\n" + registeredReporterFactoryMethods.get(reporterName);
57+
}
58+
59+
return new ReporterInfo(reporterName, type, description);
60+
}
61+
62+
private String getDescription( String reporterName ) throws SQLException {
63+
Reporter reporter = reporterFactory.createReporter(reporterName).init(connection, compatibilityProxy, reporterFactory);
64+
OracleConnection oraCon = connection.unwrap(OracleConnection.class);
65+
66+
try (OracleCallableStatement stmt = (OracleCallableStatement) oraCon.prepareCall("{ ? = call ?.get_description() }")) {
67+
stmt.registerOutParameter(1, OracleType.VARCHAR2);
68+
stmt.setORAData(2, reporter);
69+
stmt.execute();
70+
71+
return stmt.getString(1);
72+
}
73+
}
74+
75+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package org.utplsql.api.reporter.inspect;
2+
3+
import org.utplsql.api.Version;
4+
import org.utplsql.api.compatibility.CompatibilityProxy;
5+
import org.utplsql.api.reporter.CoreReporters;
6+
import org.utplsql.api.reporter.ReporterFactory;
7+
8+
import java.sql.Connection;
9+
import java.sql.SQLException;
10+
import java.util.Arrays;
11+
import java.util.HashMap;
12+
import java.util.List;
13+
import java.util.Map;
14+
import java.util.stream.Collectors;
15+
16+
class ReporterInspectorPre310 extends AbstractReporterInspector {
17+
18+
private Map<String, String> registeredReporterFactoryMethods;
19+
private Map<CoreReporters, String> descriptions;
20+
21+
ReporterInspectorPre310(ReporterFactory reporterFactory, Connection conn ) throws SQLException {
22+
super(reporterFactory, conn);
23+
}
24+
25+
private void initDefaultDescriptions() {
26+
descriptions = new HashMap<>();
27+
descriptions.put(CoreReporters.UT_COVERAGE_HTML_REPORTER, "");
28+
descriptions.put(CoreReporters.UT_COVERAGE_SONAR_REPORTER, "");
29+
descriptions.put(CoreReporters.UT_COVERALLS_REPORTER, "");
30+
descriptions.put(CoreReporters.UT_DOCUMENTATION_REPORTER, "");
31+
descriptions.put(CoreReporters.UT_SONAR_TEST_REPORTER, "");
32+
descriptions.put(CoreReporters.UT_TEAMCITY_REPORTER, "");
33+
descriptions.put(CoreReporters.UT_XUNIT_REPORTER, "");
34+
}
35+
36+
@Override
37+
protected void load() throws SQLException {
38+
initDefaultDescriptions();
39+
Version databaseVersion = new CompatibilityProxy(connection).getDatabaseVersion();
40+
registeredReporterFactoryMethods = reporterFactory.getRegisteredReporterInfo();
41+
infos = Arrays.stream(CoreReporters.values())
42+
.filter(r -> r.isAvailableFor(databaseVersion))
43+
.map(this::getReporterInfo)
44+
.collect(Collectors.toSet());
45+
}
46+
47+
private ReporterInfo getReporterInfo( CoreReporters reporter ) {
48+
49+
ReporterInfo.Type type = ReporterInfo.Type.SQL;
50+
String description = descriptions.get(reporter);
51+
52+
if ( registeredReporterFactoryMethods.containsKey(reporter.name()) ) {
53+
type = ReporterInfo.Type.SQL_WITH_JAVA;
54+
description += "\n" + registeredReporterFactoryMethods.get(reporter.name());
55+
}
56+
57+
return new ReporterInfo( reporter.name(), type, description);
58+
}
59+
}

0 commit comments

Comments
 (0)