mirror of
https://github.com/Qortal/qortal.git
synced 2025-02-12 02:05:50 +00:00
CHANGED: simplified API error annotations in API resources
FIXED: ApiErrorFactory used no context path and wrong translation key CHANGED: renamed parameters in Translator for consistency
This commit is contained in:
parent
d2aab4b446
commit
6590863201
@ -1,19 +1,27 @@
|
||||
|
||||
package api;
|
||||
|
||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||
import globalization.ContextPaths;
|
||||
import globalization.Translator;
|
||||
import io.swagger.v3.core.converter.ModelConverters;
|
||||
import io.swagger.v3.jaxrs2.Reader;
|
||||
import io.swagger.v3.jaxrs2.ReaderListener;
|
||||
import io.swagger.v3.oas.models.media.Content;
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import io.swagger.v3.oas.models.Operation;
|
||||
import io.swagger.v3.oas.models.PathItem;
|
||||
import io.swagger.v3.oas.models.examples.Example;
|
||||
import io.swagger.v3.oas.models.info.Info;
|
||||
import io.swagger.v3.oas.models.media.MediaType;
|
||||
import io.swagger.v3.oas.models.media.Schema;
|
||||
import io.swagger.v3.oas.models.responses.ApiResponse;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public class AnnotationPostProcessor implements ReaderListener {
|
||||
|
||||
private class ContextInformation {
|
||||
@ -22,13 +30,15 @@ public class AnnotationPostProcessor implements ReaderListener {
|
||||
}
|
||||
|
||||
private final Translator translator;
|
||||
private final ApiErrorFactory apiErrorFactory;
|
||||
|
||||
public AnnotationPostProcessor() {
|
||||
this(Translator.getInstance());
|
||||
this(Translator.getInstance(), ApiErrorFactory.getInstance());
|
||||
}
|
||||
|
||||
public AnnotationPostProcessor(Translator translator) {
|
||||
public AnnotationPostProcessor(Translator translator, ApiErrorFactory apiErrorFactory) {
|
||||
this.translator = translator;
|
||||
this.apiErrorFactory = apiErrorFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -41,31 +51,60 @@ public class AnnotationPostProcessor implements ReaderListener {
|
||||
Info resourceInfo = openAPI.getInfo();
|
||||
ContextInformation resourceContext = getContextInformation(openAPI.getExtensions());
|
||||
removeTranslationAnnotations(openAPI.getExtensions());
|
||||
TranslateProperty(Constants.TRANSLATABLE_INFO_PROPERTIES, resourceContext, resourceInfo);
|
||||
TranslateProperties(Constants.TRANSLATABLE_INFO_PROPERTIES, resourceContext, resourceInfo);
|
||||
|
||||
for (Map.Entry<String, PathItem> pathEntry : openAPI.getPaths().entrySet())
|
||||
{
|
||||
PathItem pathItem = pathEntry.getValue();
|
||||
ContextInformation pathContext = getContextInformation(pathItem.getExtensions(), resourceContext);
|
||||
removeTranslationAnnotations(pathItem.getExtensions());
|
||||
TranslateProperty(Constants.TRANSLATABLE_PATH_ITEM_PROPERTIES, pathContext, pathItem);
|
||||
TranslateProperties(Constants.TRANSLATABLE_PATH_ITEM_PROPERTIES, pathContext, pathItem);
|
||||
|
||||
for (Operation operation : pathItem.readOperations()) {
|
||||
ContextInformation operationContext = getContextInformation(operation.getExtensions(), pathContext);
|
||||
removeTranslationAnnotations(operation.getExtensions());
|
||||
TranslateProperty(Constants.TRANSLATABLE_OPERATION_PROPERTIES, operationContext, operation);
|
||||
TranslateProperties(Constants.TRANSLATABLE_OPERATION_PROPERTIES, operationContext, operation);
|
||||
|
||||
addApiErrorResponses(operation);
|
||||
removeApiErrorsAnnotations(operation.getExtensions());
|
||||
|
||||
for (Map.Entry<String, ApiResponse> responseEntry : operation.getResponses().entrySet()) {
|
||||
ApiResponse response = responseEntry.getValue();
|
||||
ContextInformation responseContext = getContextInformation(response.getExtensions(), operationContext);
|
||||
removeTranslationAnnotations(response.getExtensions());
|
||||
TranslateProperty(Constants.TRANSLATABLE_API_RESPONSE_PROPERTIES, responseContext, response);
|
||||
TranslateProperties(Constants.TRANSLATABLE_API_RESPONSE_PROPERTIES, responseContext, response);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private <T> void TranslateProperty(List<TranslatableProperty<T>> translatableProperties, ContextInformation context, T item) {
|
||||
private void addApiErrorResponses(Operation operation) {
|
||||
List<ApiError> apiErrors = getApiErrors(operation.getExtensions());
|
||||
if(apiErrors != null) {
|
||||
for(ApiError apiError : apiErrors) {
|
||||
String statusCode = Integer.toString(apiError.getStatus());
|
||||
ApiResponse apiResponse = operation.getResponses().get(statusCode);
|
||||
if(apiResponse == null) {
|
||||
Schema errorMessageSchema = ModelConverters.getInstance().readAllAsResolvedSchema(ApiErrorMessage.class).schema;
|
||||
MediaType mediaType = new MediaType().schema(errorMessageSchema);
|
||||
Content content = new Content().addMediaType(javax.ws.rs.core.MediaType.APPLICATION_JSON, mediaType);
|
||||
apiResponse = new ApiResponse().content(content);
|
||||
operation.getResponses().addApiResponse(statusCode, apiResponse);
|
||||
}
|
||||
|
||||
int apiErrorCode = apiError.getCode();
|
||||
ApiErrorMessage apiErrorMessage = new ApiErrorMessage(apiErrorCode, this.apiErrorFactory.getErrorMessage(apiError));
|
||||
Example example = new Example().value(apiErrorMessage);
|
||||
|
||||
// XXX: addExamples(..) is not working in Swagger 2.0.4. This bug is referenced in https://github.com/swagger-api/swagger-ui/issues/2651
|
||||
// Replace the call to .setExample(..) by .addExamples(..) when the bug is fixed.
|
||||
apiResponse.getContent().get(javax.ws.rs.core.MediaType.APPLICATION_JSON).setExample(example);
|
||||
//apiResponse.getContent().get(javax.ws.rs.core.MediaType.APPLICATION_JSON).addExamples(Integer.toString(apiErrorCode), example);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private <T> void TranslateProperties(List<TranslatableProperty<T>> translatableProperties, ContextInformation context, T item) {
|
||||
if(context.keys != null) {
|
||||
Map<String, String> keys = context.keys;
|
||||
for(TranslatableProperty<T> prop : translatableProperties) {
|
||||
@ -80,6 +119,48 @@ public class AnnotationPostProcessor implements ReaderListener {
|
||||
}
|
||||
}
|
||||
|
||||
private List<ApiError> getApiErrors(Map<String, Object> extensions) {
|
||||
if(extensions == null)
|
||||
return null;
|
||||
|
||||
List<String> apiErrorStrings = new ArrayList();
|
||||
try {
|
||||
ArrayNode apiErrorsNode = (ArrayNode)extensions.get("x-" + Constants.API_ERRORS_EXTENSION_NAME);
|
||||
if(apiErrorsNode == null)
|
||||
return null;
|
||||
|
||||
for(int i = 0; i < apiErrorsNode.size(); i++) {
|
||||
String errorString = apiErrorsNode.get(i).asText();
|
||||
apiErrorStrings.add(errorString);
|
||||
}
|
||||
} catch(Exception e) {
|
||||
// TODO: error logging
|
||||
return null;
|
||||
}
|
||||
|
||||
List<ApiError> result = new ArrayList<>();
|
||||
for(String apiErrorString : apiErrorStrings) {
|
||||
ApiError apiError = null;
|
||||
try {
|
||||
apiError = ApiError.valueOf(apiErrorString);
|
||||
} catch(IllegalArgumentException e) {
|
||||
try {
|
||||
int errorCodeInt = Integer.parseInt(apiErrorString);
|
||||
apiError = ApiError.fromCode(errorCodeInt);
|
||||
} catch (NumberFormatException ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if(apiError == null)
|
||||
return null;
|
||||
|
||||
result.add(apiError);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private ContextInformation getContextInformation(Map<String, Object> extensions) {
|
||||
return getContextInformation(extensions, null);
|
||||
}
|
||||
@ -104,11 +185,21 @@ public class AnnotationPostProcessor implements ReaderListener {
|
||||
return null;
|
||||
}
|
||||
|
||||
private void removeApiErrorsAnnotations(Map<String, Object> extensions) {
|
||||
String extensionName = Constants.API_ERRORS_EXTENSION_NAME;
|
||||
removeExtension(extensions, extensionName);
|
||||
}
|
||||
|
||||
private void removeTranslationAnnotations(Map<String, Object> extensions) {
|
||||
String extensionName = Constants.TRANSLATION_EXTENSION_NAME;
|
||||
removeExtension(extensions, extensionName);
|
||||
}
|
||||
|
||||
private void removeExtension(Map<String, Object> extensions, String extensionName) {
|
||||
if(extensions == null)
|
||||
return;
|
||||
|
||||
extensions.remove("x-" + Constants.TRANSLATION_EXTENSION_NAME);
|
||||
extensions.remove("x-" + extensionName);
|
||||
}
|
||||
|
||||
private Map<String, String> getTranslationKeys(Map<String, Object> translationDefinitions) {
|
||||
|
@ -110,6 +110,15 @@ public enum ApiError {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public static ApiError fromCode(int code) {
|
||||
for(ApiError apiError : ApiError.values()) {
|
||||
if(apiError.code == code)
|
||||
return apiError;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
int getCode() {
|
||||
return this.code;
|
||||
}
|
||||
|
@ -147,13 +147,17 @@ public class ApiErrorFactory {
|
||||
}
|
||||
|
||||
private ErrorMessageEntry createErrorMessageEntry(ApiError errorCode, String defaultTemplate, AbstractMap.SimpleEntry<String, Object>... templateValues) {
|
||||
String templateKey = String.format("%s: ApiError.%s message", ApiErrorFactory.class.getSimpleName(), errorCode.name());
|
||||
String templateKey = String.format(Constants.APIERROR_KEY, errorCode.name());
|
||||
return new ErrorMessageEntry(templateKey, defaultTemplate, templateValues);
|
||||
}
|
||||
|
||||
public String getErrorMessage(ApiError error) {
|
||||
return getErrorMessage(null, error);
|
||||
}
|
||||
|
||||
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);
|
||||
String message = this.translator.translate(locale, Constants.APIERROR_CONTEXT_PATH, errorMessage.templateKey, errorMessage.defaultTemplate, errorMessage.templateValues);
|
||||
return message;
|
||||
}
|
||||
|
||||
|
@ -48,10 +48,15 @@ public class BlocksResource {
|
||||
@Path("/{signature}")
|
||||
@Operation(
|
||||
description = "returns the block that matches the given signature",
|
||||
extensions = @Extension(name = "translation", properties = {
|
||||
@ExtensionProperty(name="path", value="GET signature"),
|
||||
@ExtensionProperty(name="description.key", value="operation:description")
|
||||
}),
|
||||
extensions = {
|
||||
@Extension(name = "translation", properties = {
|
||||
@ExtensionProperty(name="path", value="GET signature"),
|
||||
@ExtensionProperty(name="description.key", value="operation:description")
|
||||
}),
|
||||
@Extension(properties = {
|
||||
@ExtensionProperty(name="apiErrors", value="[\"INVALID_SIGNATURE\", \"BLOCK_NO_EXISTS\"]", parseValue = true),
|
||||
})
|
||||
},
|
||||
responses = {
|
||||
@ApiResponse(
|
||||
description = "the block",
|
||||
@ -61,32 +66,6 @@ public class BlocksResource {
|
||||
@ExtensionProperty(name="description.key", value="success_response:description")
|
||||
})
|
||||
}
|
||||
),
|
||||
@ApiResponse(
|
||||
responseCode = "400",
|
||||
description = "invalid signature",
|
||||
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class)),
|
||||
extensions = {
|
||||
@Extension(properties = {
|
||||
@ExtensionProperty(name="apiErrorCode", value="101")
|
||||
}),
|
||||
@Extension(name = "translation", properties = {
|
||||
@ExtensionProperty(name="description.key", value="ApiError/101")
|
||||
})
|
||||
}
|
||||
),
|
||||
@ApiResponse(
|
||||
responseCode = "422",
|
||||
description = "block does not exist",
|
||||
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class)),
|
||||
extensions = {
|
||||
@Extension(properties = {
|
||||
@ExtensionProperty(name="apiErrorCode", value="301")
|
||||
}),
|
||||
@Extension(name = "translation", properties = {
|
||||
@ExtensionProperty(name="description.key", value="ApiError/301")
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
@ -196,10 +175,15 @@ public class BlocksResource {
|
||||
@Path("/child/{signature}")
|
||||
@Operation(
|
||||
description = "returns the child block of the block that matches the given signature",
|
||||
extensions = @Extension(name = "translation", properties = {
|
||||
@ExtensionProperty(name="path", value="GET child:signature"),
|
||||
@ExtensionProperty(name="description.key", value="operation:description")
|
||||
}),
|
||||
extensions = {
|
||||
@Extension(name = "translation", properties = {
|
||||
@ExtensionProperty(name="path", value="GET child:signature"),
|
||||
@ExtensionProperty(name="description.key", value="operation:description")
|
||||
}),
|
||||
@Extension(properties = {
|
||||
@ExtensionProperty(name="apiErrors", value="[\"INVALID_SIGNATURE\", \"BLOCK_NO_EXISTS\"]", parseValue = true),
|
||||
})
|
||||
},
|
||||
responses = {
|
||||
@ApiResponse(
|
||||
description = "the block",
|
||||
@ -209,32 +193,6 @@ public class BlocksResource {
|
||||
@ExtensionProperty(name="description.key", value="success_response:description")
|
||||
})
|
||||
}
|
||||
),
|
||||
@ApiResponse(
|
||||
responseCode = "400",
|
||||
description = "invalid signature",
|
||||
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class)),
|
||||
extensions = {
|
||||
@Extension(properties = {
|
||||
@ExtensionProperty(name="apiErrorCode", value="101")
|
||||
}),
|
||||
@Extension(name = "translation", properties = {
|
||||
@ExtensionProperty(name="description.key", value="ApiError/101")
|
||||
})
|
||||
}
|
||||
),
|
||||
@ApiResponse(
|
||||
responseCode = "422",
|
||||
description = "block does not exist",
|
||||
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class)),
|
||||
extensions = {
|
||||
@Extension(properties = {
|
||||
@ExtensionProperty(name="apiErrorCode", value="301")
|
||||
}),
|
||||
@Extension(name = "translation", properties = {
|
||||
@ExtensionProperty(name="description.key", value="ApiError/301")
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
@ -303,10 +261,15 @@ public class BlocksResource {
|
||||
@Path("/generatingbalance/{signature}")
|
||||
@Operation(
|
||||
description = "calculates the generating balance of the block that will follow the block that matches the signature",
|
||||
extensions = @Extension(name = "translation", properties = {
|
||||
@ExtensionProperty(name="path", value="GET generatingbalance:signature"),
|
||||
@ExtensionProperty(name="description.key", value="operation:description")
|
||||
}),
|
||||
extensions = {
|
||||
@Extension(name = "translation", properties = {
|
||||
@ExtensionProperty(name="path", value="GET generatingbalance:signature"),
|
||||
@ExtensionProperty(name="description.key", value="operation:description")
|
||||
}),
|
||||
@Extension(properties = {
|
||||
@ExtensionProperty(name="apiErrors", value="[\"INVALID_SIGNATURE\", \"BLOCK_NO_EXISTS\"]", parseValue = true),
|
||||
})
|
||||
},
|
||||
responses = {
|
||||
@ApiResponse(
|
||||
description = "the block",
|
||||
@ -316,32 +279,6 @@ public class BlocksResource {
|
||||
@ExtensionProperty(name="description.key", value="success_response:description")
|
||||
})
|
||||
}
|
||||
),
|
||||
@ApiResponse(
|
||||
responseCode = "400",
|
||||
description = "invalid signature",
|
||||
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class)),
|
||||
extensions = {
|
||||
@Extension(properties = {
|
||||
@ExtensionProperty(name="apiErrorCode", value="101")
|
||||
}),
|
||||
@Extension(name = "translation", properties = {
|
||||
@ExtensionProperty(name="description.key", value="ApiError/101")
|
||||
})
|
||||
}
|
||||
),
|
||||
@ApiResponse(
|
||||
responseCode = "422",
|
||||
description = "block does not exist",
|
||||
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class)),
|
||||
extensions = {
|
||||
@Extension(properties = {
|
||||
@ExtensionProperty(name="apiErrorCode", value="301")
|
||||
}),
|
||||
@Extension(name = "translation", properties = {
|
||||
@ExtensionProperty(name="description.key", value="ApiError/301")
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
@ -437,10 +374,15 @@ public class BlocksResource {
|
||||
@Path("/height/{signature}")
|
||||
@Operation(
|
||||
description = "returns the block height of the block that matches the given signature",
|
||||
extensions = @Extension(name = "translation", properties = {
|
||||
@ExtensionProperty(name="path", value="GET height:signature"),
|
||||
@ExtensionProperty(name="description.key", value="operation:description")
|
||||
}),
|
||||
extensions = {
|
||||
@Extension(name = "translation", properties = {
|
||||
@ExtensionProperty(name="path", value="GET height:signature"),
|
||||
@ExtensionProperty(name="description.key", value="operation:description")
|
||||
}),
|
||||
@Extension(properties = {
|
||||
@ExtensionProperty(name="apiErrors", value="[\"INVALID_SIGNATURE\", \"BLOCK_NO_EXISTS\"]", parseValue = true),
|
||||
})
|
||||
},
|
||||
responses = {
|
||||
@ApiResponse(
|
||||
description = "the height",
|
||||
@ -450,32 +392,6 @@ public class BlocksResource {
|
||||
@ExtensionProperty(name="description.key", value="success_response:description")
|
||||
})
|
||||
}
|
||||
),
|
||||
@ApiResponse(
|
||||
responseCode = "400",
|
||||
description = "invalid signature",
|
||||
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class)),
|
||||
extensions = {
|
||||
@Extension(properties = {
|
||||
@ExtensionProperty(name="apiErrorCode", value="101")
|
||||
}),
|
||||
@Extension(name = "translation", properties = {
|
||||
@ExtensionProperty(name="description.key", value="ApiError/101")
|
||||
})
|
||||
}
|
||||
),
|
||||
@ApiResponse(
|
||||
responseCode = "422",
|
||||
description = "block does not exist",
|
||||
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class)),
|
||||
extensions = {
|
||||
@Extension(properties = {
|
||||
@ExtensionProperty(name="apiErrorCode", value="301")
|
||||
}),
|
||||
@Extension(name = "translation", properties = {
|
||||
@ExtensionProperty(name="description.key", value="ApiError/301")
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
@ -511,10 +427,15 @@ public class BlocksResource {
|
||||
@Path("/byheight/{height}")
|
||||
@Operation(
|
||||
description = "returns the block whith given height",
|
||||
extensions = @Extension(name = "translation", properties = {
|
||||
@ExtensionProperty(name="path", value="GET byheight:height"),
|
||||
@ExtensionProperty(name="description.key", value="operation:description")
|
||||
}),
|
||||
extensions = {
|
||||
@Extension(name = "translation", properties = {
|
||||
@ExtensionProperty(name="path", value="GET byheight:height"),
|
||||
@ExtensionProperty(name="description.key", value="operation:description")
|
||||
}),
|
||||
@Extension(properties = {
|
||||
@ExtensionProperty(name="apiErrors", value="[\"BLOCK_NO_EXISTS\"]", parseValue = true),
|
||||
})
|
||||
},
|
||||
responses = {
|
||||
@ApiResponse(
|
||||
description = "the block",
|
||||
@ -524,19 +445,6 @@ public class BlocksResource {
|
||||
@ExtensionProperty(name="description.key", value="success_response:description")
|
||||
})
|
||||
}
|
||||
),
|
||||
@ApiResponse(
|
||||
responseCode = "422",
|
||||
description = "block does not exist",
|
||||
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class)),
|
||||
extensions = {
|
||||
@Extension(properties = {
|
||||
@ExtensionProperty(name="apiErrorCode", value="301")
|
||||
}),
|
||||
@Extension(name = "translation", properties = {
|
||||
@ExtensionProperty(name="description.key", value="ApiError/301")
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
|
@ -8,6 +8,8 @@ import static java.util.Arrays.asList;
|
||||
import java.util.List;
|
||||
|
||||
class Constants {
|
||||
public static final String APIERROR_CONTEXT_PATH = "/Api";
|
||||
public static final String APIERROR_KEY = "ApiError/%s";
|
||||
|
||||
public static final String TRANSLATION_EXTENSION_NAME = "translation";
|
||||
public static final String TRANSLATION_PATH_EXTENSION_NAME = "path";
|
||||
@ -17,9 +19,9 @@ class Constants {
|
||||
public static final String TRANSLATION_ANNOTATION_TITLE_KEY = "title.key";
|
||||
public static final String TRANSLATION_ANNOTATION_TERMS_OF_SERVICE_KEY = "termsOfService.key";
|
||||
|
||||
public static final String API_ERRORS_EXTENSION_NAME = "apiErrors";
|
||||
public static final String API_ERROR_CODE_EXTENSION_NAME = "apiErrorCode";
|
||||
|
||||
|
||||
public static final List<TranslatableProperty<Info>> TRANSLATABLE_INFO_PROPERTIES = asList(
|
||||
new TranslatableProperty<Info>() {
|
||||
@Override public String keyName() { return TRANSLATION_ANNOTATION_DESCRIPTION_KEY; }
|
||||
|
@ -53,7 +53,7 @@ public class TranslationXmlStreamReader {
|
||||
|
||||
State state = new State(Locale.forLanguageTag("default"), "/");
|
||||
|
||||
List<TranslationEntry> result = new ArrayList<TranslationEntry>();
|
||||
List<TranslationEntry> result = new ArrayList<>();
|
||||
if (eventReader.hasNext())
|
||||
{
|
||||
XMLEvent event = eventReader.nextTag();
|
||||
|
@ -89,52 +89,52 @@ public class Translator {
|
||||
return map;
|
||||
}
|
||||
|
||||
public String translate(Locale locale, String contextPath, String templateKey, AbstractMap.Entry<String, Object>... templateValues) {
|
||||
public String translate(Locale locale, String contextPath, String keyPath, AbstractMap.Entry<String, Object>... templateValues) {
|
||||
Map<String, Object> map = createMap(templateValues);
|
||||
return translate(locale, contextPath, templateKey, map);
|
||||
return translate(locale, contextPath, keyPath, map);
|
||||
}
|
||||
|
||||
public String translate(String contextPath, String templateKey, AbstractMap.Entry<String, Object>... templateValues) {
|
||||
public String translate(String contextPath, String keyPath, AbstractMap.Entry<String, Object>... templateValues) {
|
||||
Map<String, Object> map = createMap(templateValues);
|
||||
return translate(contextPath, templateKey, map);
|
||||
return translate(contextPath, keyPath, map);
|
||||
}
|
||||
|
||||
public String translate(Locale locale, String contextPath, String templateKey, Map<String, Object> templateValues) {
|
||||
return translate(locale, contextPath, templateKey, null, templateValues);
|
||||
public String translate(Locale locale, String contextPath, String keyPath, Map<String, Object> templateValues) {
|
||||
return translate(locale, contextPath, keyPath, null, templateValues);
|
||||
}
|
||||
|
||||
public String translate(String contextPath, String templateKey, Map<String, Object> templateValues) {
|
||||
return translate(contextPath, templateKey, null, templateValues);
|
||||
public String translate(String contextPath, String keyPath, Map<String, Object> templateValues) {
|
||||
return translate(contextPath, keyPath, null, templateValues);
|
||||
}
|
||||
|
||||
public String translate(Locale locale, String contextPath, String templateKey, String defaultTemplate, AbstractMap.Entry<String, Object>... templateValues) {
|
||||
public String translate(Locale locale, String contextPath, String keyPath, String defaultTemplate, AbstractMap.Entry<String, Object>... templateValues) {
|
||||
Map<String, Object> map = createMap(templateValues);
|
||||
return translate(locale, contextPath, templateKey, defaultTemplate, map);
|
||||
return translate(locale, contextPath, keyPath, defaultTemplate, map);
|
||||
}
|
||||
|
||||
public String translate(String contextPath, String templateKey, String defaultTemplate, AbstractMap.Entry<String, Object>... templateValues) {
|
||||
public String translate(String contextPath, String keyPath, String defaultTemplate, AbstractMap.Entry<String, Object>... templateValues) {
|
||||
Map<String, Object> map = createMap(templateValues);
|
||||
return translate(contextPath, templateKey, defaultTemplate, map);
|
||||
return translate(contextPath, keyPath, defaultTemplate, map);
|
||||
}
|
||||
|
||||
public String translate(Locale locale, String contextPath, String templateKey, String defaultTemplate, Map<String, Object> templateValues) {
|
||||
public String translate(Locale locale, String contextPath, String keyPath, String defaultTemplate, Map<String, Object> templateValues) {
|
||||
// look for requested language
|
||||
String template = null;
|
||||
if(locale != null)
|
||||
template = getTemplateFromNearestPath(locale, contextPath, templateKey);
|
||||
template = getTemplateFromNearestPath(locale, contextPath, keyPath);
|
||||
|
||||
if(template != null)
|
||||
return substitute(template, templateValues);
|
||||
|
||||
return translate(contextPath, templateKey, defaultTemplate, templateValues);
|
||||
return translate(contextPath, keyPath, defaultTemplate, templateValues);
|
||||
}
|
||||
|
||||
public String translate(String contextPath, String templateKey, String defaultTemplate, Map<String, Object> templateValues) {
|
||||
public String translate(String contextPath, String keyPath, String defaultTemplate, Map<String, Object> templateValues) {
|
||||
// scan default languages
|
||||
String template = null;
|
||||
for(String language : this.settings().translationsDefaultLocales()) {
|
||||
Locale defaultLocale = Locale.forLanguageTag(language);
|
||||
template = getTemplateFromNearestPath(defaultLocale, contextPath, templateKey);
|
||||
template = getTemplateFromNearestPath(defaultLocale, contextPath, keyPath);
|
||||
if(template != null)
|
||||
break;
|
||||
}
|
||||
@ -155,14 +155,14 @@ public class Translator {
|
||||
return result;
|
||||
}
|
||||
|
||||
private String getTemplateFromNearestPath(Locale locale, String contextPath, String templateKey) {
|
||||
private String getTemplateFromNearestPath(Locale locale, String contextPath, String keyPath) {
|
||||
Map<String, String> localTranslations = this.translations.get(locale);
|
||||
if(localTranslations == null)
|
||||
return null;
|
||||
|
||||
String template = null;
|
||||
while(true) {
|
||||
String path = ContextPaths.combinePaths(contextPath, templateKey);
|
||||
String path = ContextPaths.combinePaths(contextPath, keyPath);
|
||||
template = localTranslations.get(path);
|
||||
if(template != null)
|
||||
break; // found template
|
||||
|
Loading…
x
Reference in New Issue
Block a user