Skip to content

Commit 457625d

Browse files
committed
Refactoring around commands.
I wanted to have more separation between Main-Class and actual commands. There might still be work left to do, but it's a first throw.
1 parent 2772add commit 457625d

File tree

11 files changed

+215
-146
lines changed

11 files changed

+215
-146
lines changed

src/main/java/org/utplsql/cli/Cli.java

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,48 +12,43 @@ public class Cli {
1212
static final int DEFAULT_ERROR_CODE = 1;
1313

1414
static final String HELP_CMD = "-h";
15-
private static final String RUN_CMD = "run";
16-
private static final String VERSION_CMD = "info";
1715

1816
public static void main(String[] args) {
1917

18+
int exitCode = runWithExitCode(args);
19+
20+
System.exit(exitCode);
21+
}
22+
23+
static int runWithExitCode( String[] args ) {
2024
LocaleInitializer.initLocale();
2125

2226
JCommander jc = new JCommander();
2327
jc.setProgramName("utplsql");
24-
// jc.addCommand(HELP_CMD, new HelpCommand());
25-
RunCommand runCmd = new RunCommand();
26-
VersionInfoCommand infoCmd = new VersionInfoCommand();
27-
jc.addCommand(RUN_CMD, runCmd);
28-
jc.addCommand(VERSION_CMD, infoCmd);
28+
29+
CommandProvider cmdProvider = new CommandProvider();
30+
31+
cmdProvider.commands().forEach(cmd -> jc.addCommand(cmd.getCommand(), cmd));
32+
2933
int exitCode = DEFAULT_ERROR_CODE;
3034

3135
try {
3236
jc.parse(args);
3337

34-
if (RUN_CMD.equals(jc.getParsedCommand())) {
35-
exitCode = runCmd.run();
36-
}
37-
else if ( VERSION_CMD.equals(jc.getParsedCommand()) ) {
38-
exitCode = infoCmd.run();
39-
}
40-
else {
41-
throw new ParameterException("Command not specified.");
42-
}
38+
exitCode = cmdProvider.getCommand(jc.getParsedCommand()).run();
39+
4340
} catch (ParameterException e) {
4441
if (jc.getParsedCommand() != null) {
4542
System.err.println(e.getMessage());
4643
jc.usage(jc.getParsedCommand());
4744
} else {
4845
jc.usage();
4946
}
50-
} catch ( DatabaseNotCompatibleException | UtPLSQLNotInstalledException | DatabaseConnectionFailed e ) {
51-
System.out.println(e.getMessage());
52-
} catch (Exception e) {
47+
} catch (Exception e) {
5348
e.printStackTrace();
5449
}
5550

56-
System.exit(exitCode);
51+
return exitCode;
5752
}
5853

5954
private static class HelpCommand {
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package org.utplsql.cli;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
import java.util.stream.Stream;
6+
7+
public class CommandProvider {
8+
9+
private Map<String, ICommand> commands;
10+
11+
public CommandProvider() {
12+
init();
13+
}
14+
15+
private void init() {
16+
commands = new HashMap<>();
17+
18+
addCommand(new RunCommand());
19+
addCommand(new VersionInfoCommand());
20+
}
21+
22+
private void addCommand( ICommand command ) {
23+
commands.put(command.getCommand().toLowerCase(), command);
24+
}
25+
26+
public ICommand getCommand( String key ) {
27+
if ( commands.containsKey(key))
28+
return commands.get(key.toLowerCase());
29+
else
30+
return new HelpCommand("Unknown command: '" + key + "'");
31+
}
32+
33+
public Stream<ICommand> commands() {
34+
return commands.values().stream();
35+
}
36+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package org.utplsql.cli;
2+
3+
public class HelpCommand implements ICommand {
4+
5+
private String errorMessage;
6+
7+
public HelpCommand( String errorMessage ) {
8+
this.errorMessage = errorMessage;
9+
}
10+
11+
@Override
12+
public int run() {
13+
if ( errorMessage != null )
14+
System.out.println(errorMessage);
15+
16+
return 1;
17+
}
18+
19+
@Override
20+
public String getCommand() {
21+
return "-h";
22+
}
23+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package org.utplsql.cli;
2+
3+
/** Interface to decouple JCommander commands
4+
*
5+
* @author pesse
6+
*/
7+
public interface ICommand {
8+
int run();
9+
10+
String getCommand();
11+
}

src/main/java/org/utplsql/cli/RunCommand.java

Lines changed: 89 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
import org.utplsql.api.TestRunner;
88
import org.utplsql.api.Version;
99
import org.utplsql.api.compatibility.CompatibilityProxy;
10+
import org.utplsql.api.exception.DatabaseNotCompatibleException;
1011
import org.utplsql.api.exception.SomeTestsFailedException;
12+
import org.utplsql.api.exception.UtPLSQLNotInstalledException;
1113
import org.utplsql.api.reporter.Reporter;
1214
import org.utplsql.api.reporter.ReporterFactory;
1315
import org.utplsql.cli.exception.DatabaseConnectionFailed;
@@ -30,7 +32,7 @@
3032
* @author pesse
3133
*/
3234
@Parameters(separators = "=", commandDescription = "run tests")
33-
public class RunCommand {
35+
public class RunCommand implements ICommand {
3436

3537
@Parameter(
3638
required = true,
@@ -110,102 +112,113 @@ public List<String> getTestPaths() {
110112
return testPaths;
111113
}
112114

113-
public int run() throws Exception {
115+
public int run() {
114116

115-
final List<Reporter> reporterList;
116-
final List<String> testPaths = getTestPaths();
117+
try {
117118

118-
final File baseDir = new File("").getAbsoluteFile();
119-
final FileMapperOptions[] sourceMappingOptions = {null};
120-
final FileMapperOptions[] testMappingOptions = {null};
119+
final List<Reporter> reporterList;
120+
final List<String> testPaths = getTestPaths();
121121

122-
final int[] returnCode = {0};
122+
final File baseDir = new File("").getAbsoluteFile();
123+
final FileMapperOptions[] sourceMappingOptions = {null};
124+
final FileMapperOptions[] testMappingOptions = {null};
123125

124-
sourceMappingOptions[0] = getFileMapperOptionsByParamListItem(this.sourcePathParams, baseDir);
125-
testMappingOptions[0] = getFileMapperOptionsByParamListItem(this.testPathParams, baseDir);
126+
final int[] returnCode = {0};
126127

127-
ArrayList<String> includeObjectsList;
128-
ArrayList<String> excludeObjectsList;
128+
sourceMappingOptions[0] = getFileMapperOptionsByParamListItem(this.sourcePathParams, baseDir);
129+
testMappingOptions[0] = getFileMapperOptionsByParamListItem(this.testPathParams, baseDir);
129130

130-
if (includeObjects != null && !includeObjects.isEmpty()) {
131-
includeObjectsList = new ArrayList<>(Arrays.asList(includeObjects.split(",")));
132-
} else {
133-
includeObjectsList = new ArrayList<>();
134-
}
135-
136-
if (excludeObjects != null && !excludeObjects.isEmpty()) {
137-
excludeObjectsList = new ArrayList<>(Arrays.asList(excludeObjects.split(",")));
138-
} else {
139-
excludeObjectsList = new ArrayList<>();
140-
}
131+
ArrayList<String> includeObjectsList;
132+
ArrayList<String> excludeObjectsList;
141133

142-
final ArrayList<String> finalIncludeObjectsList = includeObjectsList;
143-
final ArrayList<String> finalExcludeObjectsList = excludeObjectsList;
144-
145-
final DataSource dataSource = DataSourceProvider.getDataSource(getConnectionInfo(), getReporterManager().getNumberOfReporters()+1);
134+
if (includeObjects != null && !includeObjects.isEmpty()) {
135+
includeObjectsList = new ArrayList<>(Arrays.asList(includeObjects.split(",")));
136+
} else {
137+
includeObjectsList = new ArrayList<>();
138+
}
146139

147-
// Do the reporters initialization, so we can use the id to run and gather results.
148-
try (Connection conn = dataSource.getConnection()) {
140+
if (excludeObjects != null && !excludeObjects.isEmpty()) {
141+
excludeObjectsList = new ArrayList<>(Arrays.asList(excludeObjects.split(",")));
142+
} else {
143+
excludeObjectsList = new ArrayList<>();
144+
}
149145

150-
// Check if orai18n exists if database version is 11g
151-
RunCommandChecker.checkOracleI18nExists(conn);
146+
final ArrayList<String> finalIncludeObjectsList = includeObjectsList;
147+
final ArrayList<String> finalExcludeObjectsList = excludeObjectsList;
152148

153-
// First of all do a compatibility check and fail-fast
154-
compatibilityProxy = checkFrameworkCompatibility(conn);
155-
reporterFactory = ReporterFactoryProvider.createReporterFactory(compatibilityProxy);
149+
final DataSource dataSource = DataSourceProvider.getDataSource(getConnectionInfo(), getReporterManager().getNumberOfReporters() + 1);
156150

157-
reporterList = getReporterManager().initReporters(conn, reporterFactory, compatibilityProxy);
151+
// Do the reporters initialization, so we can use the id to run and gather results.
152+
try (Connection conn = dataSource.getConnection()) {
158153

159-
} catch (SQLException e) {
160-
if ( e.getErrorCode() == 1017 || e.getErrorCode() == 12514 ) {
161-
throw new DatabaseConnectionFailed(e);
162-
}
163-
else {
164-
throw e;
165-
}
166-
}
154+
// Check if orai18n exists if database version is 11g
155+
RunCommandChecker.checkOracleI18nExists(conn);
167156

168-
// Output a message if --failureExitCode is set but database framework is not capable of
169-
String msg = RunCommandChecker.getCheckFailOnErrorMessage(failureExitCode, compatibilityProxy.getDatabaseVersion());
170-
if ( msg != null ) {
171-
System.out.println(msg);
172-
}
157+
// First of all do a compatibility check and fail-fast
158+
compatibilityProxy = checkFrameworkCompatibility(conn);
159+
reporterFactory = ReporterFactoryProvider.createReporterFactory(compatibilityProxy);
173160

174-
ExecutorService executorService = Executors.newFixedThreadPool(1 + reporterList.size());
161+
reporterList = getReporterManager().initReporters(conn, reporterFactory, compatibilityProxy);
175162

176-
// Run tests.
177-
executorService.submit(() -> {
178-
try (Connection conn = dataSource.getConnection()) {
179-
TestRunner testRunner = new TestRunner()
180-
.addPathList(testPaths)
181-
.addReporterList(reporterList)
182-
.sourceMappingOptions(sourceMappingOptions[0])
183-
.testMappingOptions(testMappingOptions[0])
184-
.colorConsole(this.colorConsole)
185-
.failOnErrors(true)
186-
.skipCompatibilityCheck(skipCompatibilityCheck)
187-
.includeObjects(finalIncludeObjectsList)
188-
.excludeObjects(finalExcludeObjectsList);
189-
190-
testRunner.run(conn);
191-
} catch (SomeTestsFailedException e) {
192-
returnCode[0] = this.failureExitCode;
193163
} catch (SQLException e) {
194-
System.out.println(e.getMessage());
195-
returnCode[0] = Cli.DEFAULT_ERROR_CODE;
196-
executorService.shutdownNow();
164+
if (e.getErrorCode() == 1017 || e.getErrorCode() == 12514) {
165+
throw new DatabaseConnectionFailed(e);
166+
} else {
167+
throw e;
168+
}
197169
}
198-
});
199170

200-
// Gather each reporter results on a separate thread.
201-
getReporterManager().startReporterGatherers(executorService, dataSource, returnCode);
171+
// Output a message if --failureExitCode is set but database framework is not capable of
172+
String msg = RunCommandChecker.getCheckFailOnErrorMessage(failureExitCode, compatibilityProxy.getDatabaseVersion());
173+
if (msg != null) {
174+
System.out.println(msg);
175+
}
202176

203-
executorService.shutdown();
204-
executorService.awaitTermination(60, TimeUnit.MINUTES);
205-
return returnCode[0];
206-
}
177+
ExecutorService executorService = Executors.newFixedThreadPool(1 + reporterList.size());
178+
179+
// Run tests.
180+
executorService.submit(() -> {
181+
try (Connection conn = dataSource.getConnection()) {
182+
TestRunner testRunner = new TestRunner()
183+
.addPathList(testPaths)
184+
.addReporterList(reporterList)
185+
.sourceMappingOptions(sourceMappingOptions[0])
186+
.testMappingOptions(testMappingOptions[0])
187+
.colorConsole(this.colorConsole)
188+
.failOnErrors(true)
189+
.skipCompatibilityCheck(skipCompatibilityCheck)
190+
.includeObjects(finalIncludeObjectsList)
191+
.excludeObjects(finalExcludeObjectsList);
192+
193+
testRunner.run(conn);
194+
} catch (SomeTestsFailedException e) {
195+
returnCode[0] = this.failureExitCode;
196+
} catch (SQLException e) {
197+
System.out.println(e.getMessage());
198+
returnCode[0] = Cli.DEFAULT_ERROR_CODE;
199+
executorService.shutdownNow();
200+
}
201+
});
207202

203+
// Gather each reporter results on a separate thread.
204+
getReporterManager().startReporterGatherers(executorService, dataSource, returnCode);
208205

206+
executorService.shutdown();
207+
executorService.awaitTermination(60, TimeUnit.MINUTES);
208+
return returnCode[0];
209+
}
210+
catch ( DatabaseNotCompatibleException | UtPLSQLNotInstalledException | DatabaseConnectionFailed e ) {
211+
System.out.println(e.getMessage());
212+
} catch (Exception e) {
213+
e.printStackTrace();
214+
}
215+
return 1;
216+
}
217+
218+
@Override
219+
public String getCommand() {
220+
return "run";
221+
}
209222

210223

211224
/** Returns FileMapperOptions for the first item of a given param list in a baseDir

src/main/java/org/utplsql/cli/VersionInfoCommand.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
import java.util.List;
1515

1616
@Parameters(separators = "=", commandDescription = "prints version information of cli, java-api and - if connection is given - database utPLSQL framework")
17-
public class VersionInfoCommand {
17+
public class VersionInfoCommand implements ICommand {
1818

1919
@Parameter(
2020
converter = ConnectionInfo.ConnectionStringConverter.class,
@@ -54,4 +54,9 @@ public int run() {
5454

5555
return 0;
5656
}
57+
58+
@Override
59+
public String getCommand() {
60+
return "info";
61+
}
5762
}

0 commit comments

Comments
 (0)