Merge pull request #5 from KaaCee/master

HSQLDB and better help
This commit is contained in:
catbref 2018-10-03 16:35:38 +01:00 committed by GitHub
commit 0aa0796f35
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 142 additions and 33 deletions

View File

@ -17,6 +17,5 @@
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
<classpathentry kind="lib" path="lib/hsqldb-r5836.jar"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<metadata>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<versioning>
<release>r5836</release>
<versions>
<version>r5836</version>
</versions>
<lastUpdated>20180929092113</lastUpdated>
</versioning>
</metadata>

View File

@ -0,0 +1 @@
1d7f55d30c3542b76ef961749da3c40f

View File

@ -0,0 +1 @@
8bb6a2ace951f1805b9baac61bca3a548e4299cc

View File

@ -0,0 +1 @@
7d59b5596e655b2e4fd78796e7a3896b

View File

@ -0,0 +1 @@
a7d55ed9afd753fd9c620796f7d88f67a554711c

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>r5836</version>
</project>

View File

@ -0,0 +1 @@
4d667eead4590a45fd75787cd6125701

View File

@ -0,0 +1 @@
f77180541070ce99899dc281b1c4469a6b9656f0

View File

@ -17,13 +17,18 @@
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>project.local</id>
<name>project</name>
<url>file:${project.basedir}/lib</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>r5836</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/hsqldb-r5836.jar</systemPath>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>

View File

@ -3,6 +3,8 @@ package api;
import globalization.Translator;
import io.swagger.v3.jaxrs2.integration.resources.OpenApiResource;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
@ -30,16 +32,20 @@ import settings.Settings;
public class ApiClient {
private class HelpString {
private class HelpInfo {
public final Pattern pattern;
public final String fullPath;
public final String description;
public final List<String> success;
public final List<String> errors;
public HelpString(Pattern pattern, String fullPath, String description) {
public HelpInfo(Pattern pattern, String fullPath, String description, List<String> success, List<String> errors) {
this.pattern = pattern;
this.fullPath = fullPath;
this.description = description;
this.success = success;
this.errors = errors;
}
}
@ -55,11 +61,12 @@ public class ApiClient {
ApiService apiService;
private Translator translator;
List<HelpString> helpStrings;
List<HelpInfo> helpInfos;
public ApiClient(ApiService apiService, Translator translator) {
this.apiService = apiService;
this.helpStrings = getHelpStrings(apiService.getResources());
this.translator = translator;
this.helpInfos = getHelpInfos(apiService.getResources());
}
//XXX: replace singleton pattern by dependency injection?
@ -73,8 +80,10 @@ public class ApiClient {
return instance;
}
private List<HelpString> getHelpStrings(Iterable<Class<?>> resources) {
List<HelpString> result = new ArrayList<>();
private List<HelpInfo> getHelpInfos(Iterable<Class<?>> resources) {
List<HelpInfo> result = new ArrayList<>();
// TODO: need some way to realize translation from resource annotations
// scan each resource class
for (Class<?> resource : resources) {
@ -97,6 +106,38 @@ public class ApiClient {
String description = operationAnnotation.description();
// extract responses
ArrayList success = new ArrayList();
ArrayList errors = new ArrayList();
for(ApiResponse response : operationAnnotation.responses()) {
String responseDescription = response.description();
if(StringUtils.isBlank(responseDescription))
continue; // ignore responses without description
try {
// try to identify response type by status code
int responseCode = Integer.parseInt(response.responseCode());
if(responseCode >= 400) {
errors.add(responseDescription);
} else {
success.add(responseDescription);
}
} catch (NumberFormatException e) {
// try to identify response type by content
if(response.content().length > 0) {
Content content = response.content()[0];
Class<?> implementation = content.schema().implementation();
if(implementation != null && ApiErrorMessage.class.isAssignableFrom(implementation)) {
errors.add(responseDescription);
} else {
success.add(responseDescription);
}
} else {
success.add(responseDescription);
}
}
}
Path methodPath = method.getDeclaredAnnotation(Path.class);
String methodPathString = (methodPath != null) ? methodPath.value() : "";
@ -111,8 +152,9 @@ public class ApiClient {
String httpMethodString = httpMethod.value();
String fullPath = httpMethodString + " " + resourcePathString + methodPathString;
Pattern pattern = Pattern.compile("^ *(" + httpMethodString + " *)?" + getHelpPatternForPath(resourcePathString + methodPathString));
result.add(new HelpString(pattern, fullPath, description));
result.add(new HelpInfo(pattern, fullPath, description, success, errors));
}
}
}
@ -151,7 +193,7 @@ public class ApiClient {
StringBuilder result = new StringBuilder();
boolean showAll = command.trim().equalsIgnoreCase("all");
for (HelpString helpString : helpStrings) {
for (HelpInfo helpString : helpInfos) {
if (showAll || helpString.pattern.matcher(command).matches()) {
appendHelp(result, helpString);
}
@ -194,8 +236,20 @@ public class ApiClient {
return result.toString();
}
private void appendHelp(StringBuilder builder, HelpString helpString) {
builder.append(helpString.fullPath + "\n");
builder.append(helpString.description + "\n");
private void appendHelp(StringBuilder builder, HelpInfo help) {
builder.append(help.fullPath + "\n");
builder.append(" " + help.description + "\n");
if(help.success != null && help.success.size() > 0) {
builder.append(" On success returns:\n");
for(String content : help.success) {
builder.append(" " + content + "\n");
}
}
if(help.errors != null && help.errors.size() > 0) {
builder.append(" On failure returns:\n");
for(String content : help.errors) {
builder.append(" " + content + "\n");
}
}
}
}

View File

@ -151,13 +151,26 @@ public class ApiErrorFactory {
return new ErrorMessageEntry(templateKey, defaultTemplate, templateValues);
}
public String getErrorMessage(Locale locale, ApiError error) {
ErrorMessageEntry errorMessage = this.errorMessages.get(error);
String message = this.translator.translate(locale, errorMessage.templateKey, errorMessage.defaultTemplate, errorMessage.templateValues);
return message;
}
public ApiException createError(ApiError error) {
return createError(error, null);
}
public ApiException createError(ApiError error, Throwable throwable) {
Locale locale = Locale.ENGLISH; // XXX: should this be in local language?
public ApiException createError(Locale locale, ApiError error) {
return createError(locale, error, null);
}
public ApiException createError(ApiError error, Throwable throwable) {
Locale locale = Locale.ENGLISH; // default locale
return createError(locale, error, throwable);
}
public ApiException createError(Locale locale, ApiError error, Throwable throwable) {
// TODO: handle AT errors
// old AT error handling
// JSONObject jsonObject = new JSONObject();
@ -173,9 +186,8 @@ public class ApiErrorFactory {
//
//
// return new WebApplicationException(Response.status(Response.Status.BAD_REQUEST).entity(jsonObject.toJSONString()).build());
ErrorMessageEntry errorMessage = this.errorMessages.get(error);
String message = this.translator.translate(locale, errorMessage.templateKey, errorMessage.defaultTemplate, errorMessage.templateValues);
String message = getErrorMessage(locale, error);
return new ApiException(error.getStatus(), error.getCode(), message, throwable);
}
}

View File

@ -44,7 +44,8 @@ public class BlocksResource {
),
@ApiResponse(
responseCode = "422",
description = "Wallet does not exist"
description = "Error: 201 - Wallet does not exist",
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class))
)
}
)
@ -65,15 +66,18 @@ public class BlocksResource {
),
@ApiResponse(
responseCode = "400",
description = "Invalid address"
description = "102 - Invalid address",
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class))
),
@ApiResponse(
responseCode = "422",
description = "Wallet does not exist"
description = "201 - Wallet does not exist",
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class))
),
@ApiResponse(
responseCode = "422",
description = "Address does not exist in wallet"
description = "202 - Address does not exist in wallet",
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class))
)
}
)
@ -94,11 +98,13 @@ public class BlocksResource {
),
@ApiResponse(
responseCode = "400",
description = "Invalid signature"
description = "101 - Invalid signature",
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class))
),
@ApiResponse(
responseCode = "422",
description = "Block does not exist"
description = "301 - Block does not exist",
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class))
)
}
)
@ -153,11 +159,13 @@ public class BlocksResource {
),
@ApiResponse(
responseCode = "400",
description = "Invalid signature"
description = "101 - Invalid signature",
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class))
),
@ApiResponse(
responseCode = "422",
description = "Block does not exist"
description = "301 - Block does not exist",
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class))
)
}
)
@ -195,11 +203,13 @@ public class BlocksResource {
),
@ApiResponse(
responseCode = "400",
description = "Invalid signature"
description = "101 - Invalid signature",
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class))
),
@ApiResponse(
responseCode = "422",
description = "Block does not exist"
description = "301 - Block does not exist",
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class))
)
}
)
@ -275,11 +285,13 @@ public class BlocksResource {
),
@ApiResponse(
responseCode = "400",
description = "Invalid signature"
description = "101 - Invalid signature",
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class))
),
@ApiResponse(
responseCode = "422",
description = "Block does not exist"
description = "301 - Block does not exist",
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class))
)
}
)
@ -300,7 +312,8 @@ public class BlocksResource {
),
@ApiResponse(
responseCode = "422",
description = "Block does not exist"
description = "301 - Block does not exist",
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class))
)
}
)