Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Prev Previous commit
Next Next commit
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.
  • Loading branch information
pesse committed Jun 5, 2018
commit 457625d5d114331e011eeea53b32ffaeb598f8ef
35 changes: 15 additions & 20 deletions src/main/java/org/utplsql/cli/Cli.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,48 +12,43 @@ public class Cli {
static final int DEFAULT_ERROR_CODE = 1;

static final String HELP_CMD = "-h";
private static final String RUN_CMD = "run";
private static final String VERSION_CMD = "info";

public static void main(String[] args) {

int exitCode = runWithExitCode(args);

System.exit(exitCode);
}

static int runWithExitCode( String[] args ) {
LocaleInitializer.initLocale();

JCommander jc = new JCommander();
jc.setProgramName("utplsql");
// jc.addCommand(HELP_CMD, new HelpCommand());
RunCommand runCmd = new RunCommand();
VersionInfoCommand infoCmd = new VersionInfoCommand();
jc.addCommand(RUN_CMD, runCmd);
jc.addCommand(VERSION_CMD, infoCmd);

CommandProvider cmdProvider = new CommandProvider();

cmdProvider.commands().forEach(cmd -> jc.addCommand(cmd.getCommand(), cmd));

int exitCode = DEFAULT_ERROR_CODE;

try {
jc.parse(args);

if (RUN_CMD.equals(jc.getParsedCommand())) {
exitCode = runCmd.run();
}
else if ( VERSION_CMD.equals(jc.getParsedCommand()) ) {
exitCode = infoCmd.run();
}
else {
throw new ParameterException("Command not specified.");
}
exitCode = cmdProvider.getCommand(jc.getParsedCommand()).run();

} catch (ParameterException e) {
if (jc.getParsedCommand() != null) {
System.err.println(e.getMessage());
jc.usage(jc.getParsedCommand());
} else {
jc.usage();
}
} catch ( DatabaseNotCompatibleException | UtPLSQLNotInstalledException | DatabaseConnectionFailed e ) {
System.out.println(e.getMessage());
} catch (Exception e) {
} catch (Exception e) {
e.printStackTrace();
}

System.exit(exitCode);
return exitCode;
}

private static class HelpCommand {
Expand Down
36 changes: 36 additions & 0 deletions src/main/java/org/utplsql/cli/CommandProvider.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package org.utplsql.cli;

import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;

public class CommandProvider {

private Map<String, ICommand> commands;

public CommandProvider() {
init();
}

private void init() {
commands = new HashMap<>();

addCommand(new RunCommand());
addCommand(new VersionInfoCommand());
}

private void addCommand( ICommand command ) {
commands.put(command.getCommand().toLowerCase(), command);
}

public ICommand getCommand( String key ) {
if ( commands.containsKey(key))
return commands.get(key.toLowerCase());
else
return new HelpCommand("Unknown command: '" + key + "'");
}

public Stream<ICommand> commands() {
return commands.values().stream();
}
}
23 changes: 23 additions & 0 deletions src/main/java/org/utplsql/cli/HelpCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.utplsql.cli;

public class HelpCommand implements ICommand {

private String errorMessage;

public HelpCommand( String errorMessage ) {
this.errorMessage = errorMessage;
}

@Override
public int run() {
if ( errorMessage != null )
System.out.println(errorMessage);

return 1;
}

@Override
public String getCommand() {
return "-h";
}
}
11 changes: 11 additions & 0 deletions src/main/java/org/utplsql/cli/ICommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.utplsql.cli;

/** Interface to decouple JCommander commands
*
* @author pesse
*/
public interface ICommand {
int run();

String getCommand();
}
165 changes: 89 additions & 76 deletions src/main/java/org/utplsql/cli/RunCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
import org.utplsql.api.TestRunner;
import org.utplsql.api.Version;
import org.utplsql.api.compatibility.CompatibilityProxy;
import org.utplsql.api.exception.DatabaseNotCompatibleException;
import org.utplsql.api.exception.SomeTestsFailedException;
import org.utplsql.api.exception.UtPLSQLNotInstalledException;
import org.utplsql.api.reporter.Reporter;
import org.utplsql.api.reporter.ReporterFactory;
import org.utplsql.cli.exception.DatabaseConnectionFailed;
Expand All @@ -30,7 +32,7 @@
* @author pesse
*/
@Parameters(separators = "=", commandDescription = "run tests")
public class RunCommand {
public class RunCommand implements ICommand {

@Parameter(
required = true,
Expand Down Expand Up @@ -110,102 +112,113 @@ public List<String> getTestPaths() {
return testPaths;
}

public int run() throws Exception {
public int run() {

final List<Reporter> reporterList;
final List<String> testPaths = getTestPaths();
try {

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

final int[] returnCode = {0};
final File baseDir = new File("").getAbsoluteFile();
final FileMapperOptions[] sourceMappingOptions = {null};
final FileMapperOptions[] testMappingOptions = {null};

sourceMappingOptions[0] = getFileMapperOptionsByParamListItem(this.sourcePathParams, baseDir);
testMappingOptions[0] = getFileMapperOptionsByParamListItem(this.testPathParams, baseDir);
final int[] returnCode = {0};

ArrayList<String> includeObjectsList;
ArrayList<String> excludeObjectsList;
sourceMappingOptions[0] = getFileMapperOptionsByParamListItem(this.sourcePathParams, baseDir);
testMappingOptions[0] = getFileMapperOptionsByParamListItem(this.testPathParams, baseDir);

if (includeObjects != null && !includeObjects.isEmpty()) {
includeObjectsList = new ArrayList<>(Arrays.asList(includeObjects.split(",")));
} else {
includeObjectsList = new ArrayList<>();
}

if (excludeObjects != null && !excludeObjects.isEmpty()) {
excludeObjectsList = new ArrayList<>(Arrays.asList(excludeObjects.split(",")));
} else {
excludeObjectsList = new ArrayList<>();
}
ArrayList<String> includeObjectsList;
ArrayList<String> excludeObjectsList;

final ArrayList<String> finalIncludeObjectsList = includeObjectsList;
final ArrayList<String> finalExcludeObjectsList = excludeObjectsList;

final DataSource dataSource = DataSourceProvider.getDataSource(getConnectionInfo(), getReporterManager().getNumberOfReporters()+1);
if (includeObjects != null && !includeObjects.isEmpty()) {
includeObjectsList = new ArrayList<>(Arrays.asList(includeObjects.split(",")));
} else {
includeObjectsList = new ArrayList<>();
}

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

// Check if orai18n exists if database version is 11g
RunCommandChecker.checkOracleI18nExists(conn);
final ArrayList<String> finalIncludeObjectsList = includeObjectsList;
final ArrayList<String> finalExcludeObjectsList = excludeObjectsList;

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

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

} catch (SQLException e) {
if ( e.getErrorCode() == 1017 || e.getErrorCode() == 12514 ) {
throw new DatabaseConnectionFailed(e);
}
else {
throw e;
}
}
// Check if orai18n exists if database version is 11g
RunCommandChecker.checkOracleI18nExists(conn);

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

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

// Run tests.
executorService.submit(() -> {
try (Connection conn = dataSource.getConnection()) {
TestRunner testRunner = new TestRunner()
.addPathList(testPaths)
.addReporterList(reporterList)
.sourceMappingOptions(sourceMappingOptions[0])
.testMappingOptions(testMappingOptions[0])
.colorConsole(this.colorConsole)
.failOnErrors(true)
.skipCompatibilityCheck(skipCompatibilityCheck)
.includeObjects(finalIncludeObjectsList)
.excludeObjects(finalExcludeObjectsList);

testRunner.run(conn);
} catch (SomeTestsFailedException e) {
returnCode[0] = this.failureExitCode;
} catch (SQLException e) {
System.out.println(e.getMessage());
returnCode[0] = Cli.DEFAULT_ERROR_CODE;
executorService.shutdownNow();
if (e.getErrorCode() == 1017 || e.getErrorCode() == 12514) {
throw new DatabaseConnectionFailed(e);
} else {
throw e;
}
}
});

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

executorService.shutdown();
executorService.awaitTermination(60, TimeUnit.MINUTES);
return returnCode[0];
}
ExecutorService executorService = Executors.newFixedThreadPool(1 + reporterList.size());

// Run tests.
executorService.submit(() -> {
try (Connection conn = dataSource.getConnection()) {
TestRunner testRunner = new TestRunner()
.addPathList(testPaths)
.addReporterList(reporterList)
.sourceMappingOptions(sourceMappingOptions[0])
.testMappingOptions(testMappingOptions[0])
.colorConsole(this.colorConsole)
.failOnErrors(true)
.skipCompatibilityCheck(skipCompatibilityCheck)
.includeObjects(finalIncludeObjectsList)
.excludeObjects(finalExcludeObjectsList);

testRunner.run(conn);
} catch (SomeTestsFailedException e) {
returnCode[0] = this.failureExitCode;
} catch (SQLException e) {
System.out.println(e.getMessage());
returnCode[0] = Cli.DEFAULT_ERROR_CODE;
executorService.shutdownNow();
}
});

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

executorService.shutdown();
executorService.awaitTermination(60, TimeUnit.MINUTES);
return returnCode[0];
}
catch ( DatabaseNotCompatibleException | UtPLSQLNotInstalledException | DatabaseConnectionFailed e ) {
System.out.println(e.getMessage());
} catch (Exception e) {
e.printStackTrace();
}
return 1;
}

@Override
public String getCommand() {
return "run";
}


/** Returns FileMapperOptions for the first item of a given param list in a baseDir
Expand Down
7 changes: 6 additions & 1 deletion src/main/java/org/utplsql/cli/VersionInfoCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import java.util.List;

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

@Parameter(
converter = ConnectionInfo.ConnectionStringConverter.class,
Expand Down Expand Up @@ -54,4 +54,9 @@ public int run() {

return 0;
}

@Override
public String getCommand() {
return "info";
}
}
Loading