Translation fixes

Translator class no longer logs warnings for every failed translation.

Commented out unused ApiError enum entries.
Renamed some ApiError names like "_NO_EXISTS" to "_UNKNOWN".
Removed old src/main/resources/globalization/* files.

Added CheckTranslations test app.

Fixed some extraneous/missing ApiError aspects in some API-related classes.
e.g. added NAME_UNKNOWN to GET /names/{name}
This commit is contained in:
catbref 2020-03-02 12:49:15 +00:00
parent a68caa2de1
commit e425fe5d5a
16 changed files with 455 additions and 571 deletions

View File

@ -7,10 +7,10 @@ import java.util.Map;
public enum ApiError { public enum ApiError {
// COMMON // COMMON
UNKNOWN(0, 500), // UNKNOWN(0, 500),
JSON(1, 400), JSON(1, 400),
NO_BALANCE(2, 422), // NO_BALANCE(2, 422),
NOT_YET_RELEASED(3, 422), // NOT_YET_RELEASED(3, 422),
UNAUTHORIZED(4, 403), UNAUTHORIZED(4, 403),
REPOSITORY_ISSUE(5, 500), REPOSITORY_ISSUE(5, 500),
NON_PRODUCTION(6, 403), NON_PRODUCTION(6, 403),
@ -19,28 +19,28 @@ public enum ApiError {
// VALIDATION // VALIDATION
INVALID_SIGNATURE(101, 400), INVALID_SIGNATURE(101, 400),
INVALID_ADDRESS(102, 400), INVALID_ADDRESS(102, 400),
INVALID_SEED(103, 400), // INVALID_SEED(103, 400),
INVALID_AMOUNT(104, 400), // INVALID_AMOUNT(104, 400),
INVALID_FEE(105, 400), // INVALID_FEE(105, 400),
INVALID_SENDER(106, 400), // INVALID_SENDER(106, 400),
INVALID_RECIPIENT(107, 400), // INVALID_RECIPIENT(107, 400),
INVALID_NAME_LENGTH(108, 400), // INVALID_NAME_LENGTH(108, 400),
INVALID_VALUE_LENGTH(109, 400), // INVALID_VALUE_LENGTH(109, 400),
INVALID_NAME_OWNER(110, 400), // INVALID_NAME_OWNER(110, 400),
INVALID_BUYER(111, 400), // INVALID_BUYER(111, 400),
INVALID_PUBLIC_KEY(112, 400), INVALID_PUBLIC_KEY(112, 400),
INVALID_OPTIONS_LENGTH(113, 400), // INVALID_OPTIONS_LENGTH(113, 400),
INVALID_OPTION_LENGTH(114, 400), // INVALID_OPTION_LENGTH(114, 400),
INVALID_DATA(115, 400), INVALID_DATA(115, 400),
INVALID_DATA_LENGTH(116, 400), // INVALID_DATA_LENGTH(116, 400),
INVALID_UPDATE_VALUE(117, 400), // INVALID_UPDATE_VALUE(117, 400),
KEY_ALREADY_EXISTS(118, 422), // KEY_ALREADY_EXISTS(118, 422),
KEY_NOT_EXISTS(119, 404), // KEY_NOT_EXISTS(119, 404),
LAST_KEY_IS_DEFAULT_KEY_ERROR(120, 422), // LAST_KEY_IS_DEFAULT_KEY_ERROR(120, 422),
FEE_LESS_REQUIRED(121, 422), // FEE_LESS_REQUIRED(121, 422),
WALLET_NOT_IN_SYNC(122, 422), // WALLET_NOT_IN_SYNC(122, 422),
INVALID_NETWORK_ADDRESS(123, 404), INVALID_NETWORK_ADDRESS(123, 404),
ADDRESS_NO_EXISTS(124, 404), ADDRESS_UNKNOWN(124, 404),
INVALID_CRITERIA(125, 400), INVALID_CRITERIA(125, 400),
INVALID_REFERENCE(126, 400), INVALID_REFERENCE(126, 400),
TRANSFORMATION_ERROR(127, 400), TRANSFORMATION_ERROR(127, 400),
@ -49,72 +49,72 @@ public enum ApiError {
CANNOT_MINT(130, 400), CANNOT_MINT(130, 400),
// WALLET // WALLET
WALLET_NO_EXISTS(201, 404), // WALLET_NO_EXISTS(201, 404),
WALLET_ADDRESS_NO_EXISTS(202, 404), // WALLET_ADDRESS_NO_EXISTS(202, 404),
WALLET_LOCKED(203, 422), // WALLET_LOCKED(203, 422),
WALLET_ALREADY_EXISTS(204, 422), // WALLET_ALREADY_EXISTS(204, 422),
WALLET_API_CALL_FORBIDDEN_BY_USER(205, 403), // WALLET_API_CALL_FORBIDDEN_BY_USER(205, 403),
// BLOCKS // BLOCKS
BLOCK_NO_EXISTS(301, 404), BLOCK_UNKNOWN(301, 404),
// TRANSACTIONS // TRANSACTIONS
TRANSACTION_NO_EXISTS(311, 404), TRANSACTION_UNKNOWN(311, 404),
PUBLIC_KEY_NOT_FOUND(304, 404), PUBLIC_KEY_NOT_FOUND(304, 404),
TRANSACTION_INVALID(312, 400), TRANSACTION_INVALID(312, 400),
// NAMING // NAMING
NAME_NO_EXISTS(401, 404), NAME_UNKNOWN(401, 404),
NAME_ALREADY_EXISTS(402, 422), // NAME_ALREADY_EXISTS(402, 422),
NAME_ALREADY_FOR_SALE(403, 422), // NAME_ALREADY_FOR_SALE(403, 422),
NAME_NOT_LOWER_CASE(404, 422), // NAME_NOT_LOWER_CASE(404, 422),
NAME_SALE_NO_EXISTS(410, 404), // NAME_SALE_NO_EXISTS(410, 404),
BUYER_ALREADY_OWNER(411, 422), // BUYER_ALREADY_OWNER(411, 422),
// POLLS // POLLS
POLL_NO_EXISTS(501, 404), // POLL_NO_EXISTS(501, 404),
POLL_ALREADY_EXISTS(502, 422), // POLL_ALREADY_EXISTS(502, 422),
DUPLICATE_OPTION(503, 422), // DUPLICATE_OPTION(503, 422),
POLL_OPTION_NO_EXISTS(504, 404), // POLL_OPTION_NO_EXISTS(504, 404),
ALREADY_VOTED_FOR_THAT_OPTION(505, 422), // ALREADY_VOTED_FOR_THAT_OPTION(505, 422),
// ASSET // ASSET
INVALID_ASSET_ID(601, 400), INVALID_ASSET_ID(601, 400),
INVALID_ORDER_ID(602, 400), INVALID_ORDER_ID(602, 400),
ORDER_NO_EXISTS(603, 404), ORDER_UNKNOWN(603, 404),
// NAME PAYMENTS // NAME PAYMENTS
NAME_NOT_REGISTERED(701, 422), // NAME_NOT_REGISTERED(701, 422),
NAME_FOR_SALE(702, 422), // NAME_FOR_SALE(702, 422),
NAME_WITH_SPACE(703, 422), // NAME_WITH_SPACE(703, 422),
// ATs // ATs
INVALID_DESC_LENGTH(801, 400), // INVALID_DESC_LENGTH(801, 400),
EMPTY_CODE(802, 400), // EMPTY_CODE(802, 400),
DATA_SIZE(803, 400), // DATA_SIZE(803, 400),
NULL_PAGES(804, 400), // NULL_PAGES(804, 400),
INVALID_TYPE_LENGTH(805, 400), // INVALID_TYPE_LENGTH(805, 400),
INVALID_TAGS_LENGTH(806, 400), // INVALID_TAGS_LENGTH(806, 400),
INVALID_CREATION_BYTES(809, 400), // INVALID_CREATION_BYTES(809, 400),
// BLOG/Namestorage // BLOG/Namestorage
BODY_EMPTY(901, 400), // BODY_EMPTY(901, 400),
BLOG_DISABLED(902, 403), // BLOG_DISABLED(902, 403),
NAME_NOT_OWNER(903, 422), // NAME_NOT_OWNER(903, 422),
TX_AMOUNT(904, 400), // TX_AMOUNT(904, 400),
BLOG_ENTRY_NO_EXISTS(905, 404), // BLOG_ENTRY_NO_EXISTS(905, 404),
BLOG_EMPTY(906, 404), // BLOG_EMPTY(906, 404),
POSTID_EMPTY(907, 400), // POSTID_EMPTY(907, 400),
POST_NOT_EXISTING(908, 404), // POST_NOT_EXISTING(908, 404),
COMMENTING_DISABLED(909, 403), // COMMENTING_DISABLED(909, 403),
COMMENT_NOT_EXISTING(910, 404), // COMMENT_NOT_EXISTING(910, 404),
INVALID_COMMENT_OWNER(911, 422), // INVALID_COMMENT_OWNER(911, 422),
// Messages // Messages
MESSAGE_FORMAT_NOT_HEX(1001, 400), // MESSAGE_FORMAT_NOT_HEX(1001, 400),
MESSAGE_BLANK(1002, 400), // MESSAGE_BLANK(1002, 400),
NO_PUBLIC_KEY(1003, 422), // NO_PUBLIC_KEY(1003, 422),
MESSAGESIZE_EXCEEDED(1004, 400), // MESSAGESIZE_EXCEEDED(1004, 400),
// Groups // Groups
GROUP_UNKNOWN(1101, 404); GROUP_UNKNOWN(1101, 404);

View File

@ -410,7 +410,7 @@ public class AssetsResource {
} }
) )
@ApiErrors({ @ApiErrors({
ApiError.INVALID_ORDER_ID, ApiError.ORDER_NO_EXISTS, ApiError.REPOSITORY_ISSUE ApiError.INVALID_ORDER_ID, ApiError.ORDER_UNKNOWN, ApiError.REPOSITORY_ISSUE
}) })
public OrderData getAssetOrder(@PathParam("orderid") String orderId58) { public OrderData getAssetOrder(@PathParam("orderid") String orderId58) {
// Decode orderID // Decode orderID
@ -424,7 +424,7 @@ public class AssetsResource {
try (final Repository repository = RepositoryManager.getRepository()) { try (final Repository repository = RepositoryManager.getRepository()) {
OrderData orderData = repository.getAssetRepository().fromOrderId(orderId); OrderData orderData = repository.getAssetRepository().fromOrderId(orderId);
if (orderData == null) if (orderData == null)
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.ORDER_NO_EXISTS); throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.ORDER_UNKNOWN);
return orderData; return orderData;
} catch (DataException e) { } catch (DataException e) {
@ -451,7 +451,7 @@ public class AssetsResource {
} }
) )
@ApiErrors({ @ApiErrors({
ApiError.INVALID_ORDER_ID, ApiError.ORDER_NO_EXISTS, ApiError.REPOSITORY_ISSUE ApiError.INVALID_ORDER_ID, ApiError.ORDER_UNKNOWN, ApiError.REPOSITORY_ISSUE
}) })
public List<TradeData> getAssetOrderTrades(@PathParam("orderid") String orderId58, @Parameter( public List<TradeData> getAssetOrderTrades(@PathParam("orderid") String orderId58, @Parameter(
ref = "limit" ref = "limit"
@ -471,7 +471,7 @@ public class AssetsResource {
try (final Repository repository = RepositoryManager.getRepository()) { try (final Repository repository = RepositoryManager.getRepository()) {
OrderData orderData = repository.getAssetRepository().fromOrderId(orderId); OrderData orderData = repository.getAssetRepository().fromOrderId(orderId);
if (orderData == null) if (orderData == null)
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.ORDER_NO_EXISTS); throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.ORDER_UNKNOWN);
return repository.getAssetRepository().getOrdersTrades(orderId, limit, offset, reverse); return repository.getAssetRepository().getOrdersTrades(orderId, limit, offset, reverse);
} catch (DataException e) { } catch (DataException e) {
@ -497,7 +497,7 @@ public class AssetsResource {
} }
) )
@ApiErrors({ @ApiErrors({
ApiError.INVALID_ADDRESS, ApiError.ADDRESS_NO_EXISTS, ApiError.REPOSITORY_ISSUE ApiError.INVALID_ADDRESS, ApiError.ADDRESS_UNKNOWN, ApiError.REPOSITORY_ISSUE
}) })
public List<OrderData> getAccountOrders(@PathParam("address") String address, @QueryParam("includeClosed") boolean includeClosed, public List<OrderData> getAccountOrders(@PathParam("address") String address, @QueryParam("includeClosed") boolean includeClosed,
@QueryParam("includeFulfilled") boolean includeFulfilled, @Parameter( @QueryParam("includeFulfilled") boolean includeFulfilled, @Parameter(
@ -514,11 +514,11 @@ public class AssetsResource {
AccountData accountData = repository.getAccountRepository().getAccount(address); AccountData accountData = repository.getAccountRepository().getAccount(address);
if (accountData == null) if (accountData == null)
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.ADDRESS_NO_EXISTS); throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.ADDRESS_UNKNOWN);
byte[] publicKey = accountData.getPublicKey(); byte[] publicKey = accountData.getPublicKey();
if (publicKey == null) if (publicKey == null)
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.ADDRESS_NO_EXISTS); throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.ADDRESS_UNKNOWN);
return repository.getAssetRepository().getAccountsOrders(publicKey, includeClosed, includeFulfilled, limit, offset, reverse); return repository.getAssetRepository().getAccountsOrders(publicKey, includeClosed, includeFulfilled, limit, offset, reverse);
} catch (ApiException e) { } catch (ApiException e) {
@ -546,7 +546,7 @@ public class AssetsResource {
} }
) )
@ApiErrors({ @ApiErrors({
ApiError.INVALID_ADDRESS, ApiError.ADDRESS_NO_EXISTS, ApiError.REPOSITORY_ISSUE ApiError.INVALID_ADDRESS, ApiError.ADDRESS_UNKNOWN, ApiError.REPOSITORY_ISSUE
}) })
public List<OrderData> getAccountAssetPairOrders(@PathParam("address") String address, @PathParam("assetid") int assetId, public List<OrderData> getAccountAssetPairOrders(@PathParam("address") String address, @PathParam("assetid") int assetId,
@PathParam("otherassetid") int otherAssetId, @QueryParam("isClosed") Boolean isClosed, @QueryParam("isFulfilled") Boolean isFulfilled, @Parameter( @PathParam("otherassetid") int otherAssetId, @QueryParam("isClosed") Boolean isClosed, @QueryParam("isFulfilled") Boolean isFulfilled, @Parameter(
@ -563,11 +563,11 @@ public class AssetsResource {
AccountData accountData = repository.getAccountRepository().getAccount(address); AccountData accountData = repository.getAccountRepository().getAccount(address);
if (accountData == null) if (accountData == null)
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.ADDRESS_NO_EXISTS); throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.ADDRESS_UNKNOWN);
byte[] publicKey = accountData.getPublicKey(); byte[] publicKey = accountData.getPublicKey();
if (publicKey == null) if (publicKey == null)
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.ADDRESS_NO_EXISTS); throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.ADDRESS_UNKNOWN);
if (!repository.getAssetRepository().assetExists(assetId)) if (!repository.getAssetRepository().assetExists(assetId))
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_ASSET_ID); throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_ASSET_ID);

View File

@ -59,7 +59,7 @@ public class BlocksResource {
} }
) )
@ApiErrors({ @ApiErrors({
ApiError.INVALID_SIGNATURE, ApiError.BLOCK_NO_EXISTS, ApiError.REPOSITORY_ISSUE ApiError.INVALID_SIGNATURE, ApiError.BLOCK_UNKNOWN, ApiError.REPOSITORY_ISSUE
}) })
public BlockData getBlock(@PathParam("signature") String signature58) { public BlockData getBlock(@PathParam("signature") String signature58) {
// Decode signature // Decode signature
@ -98,7 +98,7 @@ public class BlocksResource {
} }
) )
@ApiErrors({ @ApiErrors({
ApiError.INVALID_SIGNATURE, ApiError.BLOCK_NO_EXISTS, ApiError.REPOSITORY_ISSUE ApiError.INVALID_SIGNATURE, ApiError.BLOCK_UNKNOWN, ApiError.REPOSITORY_ISSUE
}) })
public List<TransactionData> getBlockTransactions(@PathParam("signature") String signature58, @Parameter( public List<TransactionData> getBlockTransactions(@PathParam("signature") String signature58, @Parameter(
ref = "limit" ref = "limit"
@ -117,7 +117,7 @@ public class BlocksResource {
try (final Repository repository = RepositoryManager.getRepository()) { try (final Repository repository = RepositoryManager.getRepository()) {
if (repository.getBlockRepository().getHeightFromSignature(signature) == 0) if (repository.getBlockRepository().getHeightFromSignature(signature) == 0)
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.BLOCK_NO_EXISTS); throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.BLOCK_UNKNOWN);
return repository.getBlockRepository().getTransactionsFromSignature(signature, limit, offset, reverse); return repository.getBlockRepository().getTransactionsFromSignature(signature, limit, offset, reverse);
} catch (ApiException e) { } catch (ApiException e) {
@ -144,13 +144,11 @@ public class BlocksResource {
} }
) )
@ApiErrors({ @ApiErrors({
ApiError.BLOCK_NO_EXISTS, ApiError.REPOSITORY_ISSUE ApiError.REPOSITORY_ISSUE
}) })
public BlockData getFirstBlock() { public BlockData getFirstBlock() {
try (final Repository repository = RepositoryManager.getRepository()) { try (final Repository repository = RepositoryManager.getRepository()) {
return repository.getBlockRepository().fromHeight(1); return repository.getBlockRepository().fromHeight(1);
} catch (ApiException e) {
throw e;
} catch (DataException e) { } catch (DataException e) {
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e); throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e);
} }
@ -173,13 +171,11 @@ public class BlocksResource {
} }
) )
@ApiErrors({ @ApiErrors({
ApiError.BLOCK_NO_EXISTS, ApiError.REPOSITORY_ISSUE ApiError.REPOSITORY_ISSUE
}) })
public BlockData getLastBlock() { public BlockData getLastBlock() {
try (final Repository repository = RepositoryManager.getRepository()) { try (final Repository repository = RepositoryManager.getRepository()) {
return repository.getBlockRepository().getLastBlock(); return repository.getBlockRepository().getLastBlock();
} catch (ApiException e) {
throw e;
} catch (DataException e) { } catch (DataException e) {
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e); throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e);
} }
@ -202,7 +198,7 @@ public class BlocksResource {
} }
) )
@ApiErrors({ @ApiErrors({
ApiError.INVALID_SIGNATURE, ApiError.BLOCK_NO_EXISTS, ApiError.REPOSITORY_ISSUE ApiError.INVALID_SIGNATURE, ApiError.BLOCK_UNKNOWN, ApiError.REPOSITORY_ISSUE
}) })
public BlockData getChild(@PathParam("signature") String signature58) { public BlockData getChild(@PathParam("signature") String signature58) {
// Decode signature // Decode signature
@ -218,13 +214,13 @@ public class BlocksResource {
// Check block exists // Check block exists
if (blockData == null) if (blockData == null)
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.BLOCK_NO_EXISTS); throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.BLOCK_UNKNOWN);
BlockData childBlockData = repository.getBlockRepository().fromReference(signature); BlockData childBlockData = repository.getBlockRepository().fromReference(signature);
// Check child block exists // Check child block exists
if (childBlockData == null) if (childBlockData == null)
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.BLOCK_NO_EXISTS); throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.BLOCK_UNKNOWN);
return childBlockData; return childBlockData;
} catch (ApiException e) { } catch (ApiException e) {
@ -282,7 +278,7 @@ public class BlocksResource {
} }
) )
@ApiErrors({ @ApiErrors({
ApiError.INVALID_SIGNATURE, ApiError.BLOCK_NO_EXISTS, ApiError.REPOSITORY_ISSUE ApiError.INVALID_SIGNATURE, ApiError.BLOCK_UNKNOWN, ApiError.REPOSITORY_ISSUE
}) })
public int getHeight(@PathParam("signature") String signature58) { public int getHeight(@PathParam("signature") String signature58) {
// Decode signature // Decode signature
@ -298,7 +294,7 @@ public class BlocksResource {
// Check block exists // Check block exists
if (blockData == null) if (blockData == null)
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.BLOCK_NO_EXISTS); throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.BLOCK_UNKNOWN);
return blockData.getHeight(); return blockData.getHeight();
} catch (ApiException e) { } catch (ApiException e) {
@ -325,13 +321,13 @@ public class BlocksResource {
} }
) )
@ApiErrors({ @ApiErrors({
ApiError.BLOCK_NO_EXISTS, ApiError.REPOSITORY_ISSUE ApiError.BLOCK_UNKNOWN, ApiError.REPOSITORY_ISSUE
}) })
public BlockData getByHeight(@PathParam("height") int height) { public BlockData getByHeight(@PathParam("height") int height) {
try (final Repository repository = RepositoryManager.getRepository()) { try (final Repository repository = RepositoryManager.getRepository()) {
BlockData blockData = repository.getBlockRepository().fromHeight(height); BlockData blockData = repository.getBlockRepository().fromHeight(height);
if (blockData == null) if (blockData == null)
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.BLOCK_NO_EXISTS); throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.BLOCK_UNKNOWN);
return blockData; return blockData;
} catch (ApiException e) { } catch (ApiException e) {
@ -357,17 +353,17 @@ public class BlocksResource {
} }
) )
@ApiErrors({ @ApiErrors({
ApiError.BLOCK_NO_EXISTS, ApiError.REPOSITORY_ISSUE ApiError.BLOCK_UNKNOWN, ApiError.REPOSITORY_ISSUE
}) })
public BlockData getByTimestamp(@PathParam("timestamp") long timestamp) { public BlockData getByTimestamp(@PathParam("timestamp") long timestamp) {
try (final Repository repository = RepositoryManager.getRepository()) { try (final Repository repository = RepositoryManager.getRepository()) {
int height = repository.getBlockRepository().getHeightFromTimestamp(timestamp); int height = repository.getBlockRepository().getHeightFromTimestamp(timestamp);
if (height == 0) if (height == 0)
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.BLOCK_NO_EXISTS); throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.BLOCK_UNKNOWN);
BlockData blockData = repository.getBlockRepository().fromHeight(height); BlockData blockData = repository.getBlockRepository().fromHeight(height);
if (blockData == null) if (blockData == null)
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.BLOCK_NO_EXISTS); throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.BLOCK_UNKNOWN);
return blockData; return blockData;
} catch (ApiException e) { } catch (ApiException e) {
@ -396,7 +392,7 @@ public class BlocksResource {
} }
) )
@ApiErrors({ @ApiErrors({
ApiError.BLOCK_NO_EXISTS, ApiError.REPOSITORY_ISSUE ApiError.REPOSITORY_ISSUE
}) })
public List<BlockData> getBlockRange(@PathParam("height") int height, @Parameter( public List<BlockData> getBlockRange(@PathParam("height") int height, @Parameter(
ref = "count" ref = "count"
@ -414,8 +410,6 @@ public class BlocksResource {
} }
return blocks; return blocks;
} catch (ApiException e) {
throw e;
} catch (DataException e) { } catch (DataException e) {
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e); throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e);
} }

View File

@ -23,6 +23,7 @@ import javax.ws.rs.core.MediaType;
import org.qortal.api.ApiError; import org.qortal.api.ApiError;
import org.qortal.api.ApiErrors; import org.qortal.api.ApiErrors;
import org.qortal.api.ApiException;
import org.qortal.api.ApiExceptionFactory; import org.qortal.api.ApiExceptionFactory;
import org.qortal.api.model.NameSummary; import org.qortal.api.model.NameSummary;
import org.qortal.crypto.Crypto; import org.qortal.crypto.Crypto;
@ -122,10 +123,17 @@ public class NamesResource {
) )
} }
) )
@ApiErrors({ApiError.REPOSITORY_ISSUE}) @ApiErrors({ApiError.NAME_UNKNOWN, ApiError.REPOSITORY_ISSUE})
public NameData getName(@PathParam("name") String name) { public NameData getName(@PathParam("name") String name) {
try (final Repository repository = RepositoryManager.getRepository()) { try (final Repository repository = RepositoryManager.getRepository()) {
return repository.getNameRepository().fromName(name); NameData nameData = repository.getNameRepository().fromName(name);
if (nameData == null)
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.NAME_UNKNOWN);
return nameData;
} catch (ApiException e) {
throw e;
} catch (DataException e) { } catch (DataException e) {
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e); throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e);
} }

View File

@ -137,7 +137,7 @@ public class PeersResource {
} }
) )
@ApiErrors({ @ApiErrors({
ApiError.INVALID_DATA, ApiError.REPOSITORY_ISSUE ApiError.INVALID_NETWORK_ADDRESS, ApiError.REPOSITORY_ISSUE
}) })
public String addPeer(String address) { public String addPeer(String address) {
Security.checkApiCallAllowed(request); Security.checkApiCallAllowed(request);
@ -151,7 +151,7 @@ public class PeersResource {
return "true"; return "true";
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_DATA); throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_NETWORK_ADDRESS);
} catch (ApiException e) { } catch (ApiException e) {
throw e; throw e;
} catch (DataException e) { } catch (DataException e) {
@ -188,7 +188,7 @@ public class PeersResource {
} }
) )
@ApiErrors({ @ApiErrors({
ApiError.INVALID_DATA, ApiError.REPOSITORY_ISSUE ApiError.INVALID_NETWORK_ADDRESS, ApiError.REPOSITORY_ISSUE
}) })
public String removePeer(String address) { public String removePeer(String address) {
Security.checkApiCallAllowed(request); Security.checkApiCallAllowed(request);
@ -199,7 +199,7 @@ public class PeersResource {
boolean wasKnown = Network.getInstance().forgetPeer(peerAddress); boolean wasKnown = Network.getInstance().forgetPeer(peerAddress);
return wasKnown ? "true" : "false"; return wasKnown ? "true" : "false";
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_DATA); throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_NETWORK_ADDRESS);
} catch (ApiException e) { } catch (ApiException e) {
throw e; throw e;
} catch (DataException e) { } catch (DataException e) {
@ -223,7 +223,7 @@ public class PeersResource {
} }
) )
@ApiErrors({ @ApiErrors({
ApiError.INVALID_DATA, ApiError.REPOSITORY_ISSUE ApiError.REPOSITORY_ISSUE
}) })
public String removeKnownPeers(String address) { public String removeKnownPeers(String address) {
Security.checkApiCallAllowed(request); Security.checkApiCallAllowed(request);
@ -232,8 +232,6 @@ public class PeersResource {
int numDeleted = Network.getInstance().forgetAllPeers(); int numDeleted = Network.getInstance().forgetAllPeers();
return numDeleted != 0 ? "true" : "false"; return numDeleted != 0 ? "true" : "false";
} catch (ApiException e) {
throw e;
} catch (DataException e) { } catch (DataException e) {
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e); throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e);
} }

View File

@ -69,7 +69,7 @@ public class TransactionsResource {
} }
) )
@ApiErrors({ @ApiErrors({
ApiError.INVALID_SIGNATURE, ApiError.TRANSACTION_NO_EXISTS, ApiError.REPOSITORY_ISSUE ApiError.INVALID_SIGNATURE, ApiError.TRANSACTION_UNKNOWN, ApiError.REPOSITORY_ISSUE
}) })
public TransactionData getTransactionBySignature(@PathParam("signature") String signature58) { public TransactionData getTransactionBySignature(@PathParam("signature") String signature58) {
byte[] signature; byte[] signature;
@ -82,7 +82,7 @@ public class TransactionsResource {
try (final Repository repository = RepositoryManager.getRepository()) { try (final Repository repository = RepositoryManager.getRepository()) {
TransactionData transactionData = repository.getTransactionRepository().fromSignature(signature); TransactionData transactionData = repository.getTransactionRepository().fromSignature(signature);
if (transactionData == null) if (transactionData == null)
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.TRANSACTION_NO_EXISTS); throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.TRANSACTION_UNKNOWN);
return transactionData; return transactionData;
} catch (ApiException e) { } catch (ApiException e) {
@ -110,7 +110,7 @@ public class TransactionsResource {
} }
) )
@ApiErrors({ @ApiErrors({
ApiError.INVALID_SIGNATURE, ApiError.TRANSACTION_NO_EXISTS, ApiError.REPOSITORY_ISSUE, ApiError.TRANSFORMATION_ERROR ApiError.INVALID_SIGNATURE, ApiError.TRANSACTION_UNKNOWN, ApiError.REPOSITORY_ISSUE, ApiError.TRANSFORMATION_ERROR
}) })
public String getRawTransactionBySignature(@PathParam("signature") String signature58) { public String getRawTransactionBySignature(@PathParam("signature") String signature58) {
byte[] signature; byte[] signature;
@ -123,7 +123,7 @@ public class TransactionsResource {
try (final Repository repository = RepositoryManager.getRepository()) { try (final Repository repository = RepositoryManager.getRepository()) {
TransactionData transactionData = repository.getTransactionRepository().fromSignature(signature); TransactionData transactionData = repository.getTransactionRepository().fromSignature(signature);
if (transactionData == null) if (transactionData == null)
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.TRANSACTION_NO_EXISTS); throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.TRANSACTION_UNKNOWN);
byte[] transactionBytes = TransactionTransformer.toBytes(transactionData); byte[] transactionBytes = TransactionTransformer.toBytes(transactionData);
@ -154,7 +154,7 @@ public class TransactionsResource {
} }
) )
@ApiErrors({ @ApiErrors({
ApiError.INVALID_REFERENCE, ApiError.TRANSACTION_NO_EXISTS, ApiError.REPOSITORY_ISSUE ApiError.INVALID_REFERENCE, ApiError.TRANSACTION_UNKNOWN, ApiError.REPOSITORY_ISSUE
}) })
public TransactionData getTransactionByReference(@PathParam("reference") String reference58) { public TransactionData getTransactionByReference(@PathParam("reference") String reference58) {
byte[] reference; byte[] reference;
@ -167,7 +167,7 @@ public class TransactionsResource {
try (final Repository repository = RepositoryManager.getRepository()) { try (final Repository repository = RepositoryManager.getRepository()) {
TransactionData transactionData = repository.getTransactionRepository().fromReference(reference); TransactionData transactionData = repository.getTransactionRepository().fromReference(reference);
if (transactionData == null) if (transactionData == null)
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.TRANSACTION_NO_EXISTS); throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.TRANSACTION_UNKNOWN);
return transactionData; return transactionData;
} catch (ApiException e) { } catch (ApiException e) {
@ -196,7 +196,7 @@ public class TransactionsResource {
} }
) )
@ApiErrors({ @ApiErrors({
ApiError.INVALID_SIGNATURE, ApiError.BLOCK_NO_EXISTS, ApiError.REPOSITORY_ISSUE ApiError.INVALID_SIGNATURE, ApiError.BLOCK_UNKNOWN, ApiError.REPOSITORY_ISSUE
}) })
public List<TransactionData> getBlockTransactions(@PathParam("signature") String signature58, @Parameter( public List<TransactionData> getBlockTransactions(@PathParam("signature") String signature58, @Parameter(
ref = "limit" ref = "limit"
@ -215,7 +215,7 @@ public class TransactionsResource {
try (final Repository repository = RepositoryManager.getRepository()) { try (final Repository repository = RepositoryManager.getRepository()) {
if (repository.getBlockRepository().getHeightFromSignature(signature) == 0) if (repository.getBlockRepository().getHeightFromSignature(signature) == 0)
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.BLOCK_NO_EXISTS); throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.BLOCK_UNKNOWN);
return repository.getBlockRepository().getTransactionsFromSignature(signature, limit, offset, reverse); return repository.getBlockRepository().getTransactionsFromSignature(signature, limit, offset, reverse);
} catch (ApiException e) { } catch (ApiException e) {

View File

@ -17,36 +17,32 @@ import org.apache.logging.log4j.Logger;
public enum BIP39WordList { public enum BIP39WordList {
INSTANCE; INSTANCE;
private Logger LOGGER = LogManager.getLogger(BIP39WordList.class); private static final Logger LOGGER = LogManager.getLogger(BIP39WordList.class);
private Map<String, List<String>> wordListsByLang; private static final Map<String, List<String>> wordListsByLang = new HashMap<>();
private BIP39WordList() {
wordListsByLang = new HashMap<>();
}
public synchronized List<String> getByLang(String lang) { public synchronized List<String> getByLang(String lang) {
List<String> wordList = wordListsByLang.get(lang); List<String> wordList = wordListsByLang.get(lang);
if (wordList == null) { if (wordList == null && !wordListsByLang.containsKey(lang)) {
ClassLoader loader = this.getClass().getClassLoader(); ClassLoader loader = this.getClass().getClassLoader();
try (InputStream inputStream = loader.getResourceAsStream("BIP39/wordlist_" + lang + ".txt")) { try (InputStream inputStream = loader.getResourceAsStream("BIP39/wordlist_" + lang + ".txt")) {
if (inputStream == null) { if (inputStream == null)
LOGGER.warn(String.format("Can't locate '%s' BIP39 wordlist", lang)); LOGGER.warn(String.format("Can't locate '%s' BIP39 wordlist", lang));
return null;
}
wordList = new BufferedReader(new InputStreamReader(inputStream)).lines().collect(Collectors.toList()); wordList = new BufferedReader(new InputStreamReader(inputStream)).lines().collect(Collectors.toList());
} catch (IOException e) { } catch (IOException e) {
LOGGER.warn(String.format("Error reading '%s' BIP39 wordlist", lang), e); LOGGER.warn(String.format("Error reading '%s' BIP39 wordlist: %s", lang, e.getMessage()));
return null;
} }
wordListsByLang.put(lang, wordList); wordListsByLang.put(lang, wordList);
} }
return Collections.unmodifiableList(wordList); if (wordList != null)
return Collections.unmodifiableList(wordList);
else
return null;
} }
} }

View File

@ -6,6 +6,7 @@ import java.util.Map;
import java.util.MissingFormatArgumentException; import java.util.MissingFormatArgumentException;
import java.util.MissingResourceException; import java.util.MissingResourceException;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import java.util.Set;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
@ -13,35 +14,12 @@ import org.apache.logging.log4j.Logger;
public enum Translator { public enum Translator {
INSTANCE; INSTANCE;
private final Logger LOGGER = LogManager.getLogger(Translator.class); private static final Logger LOGGER = LogManager.getLogger(Translator.class);
private final String DEFAULT_LANG = Locale.getDefault().getLanguage(); private static final String DEFAULT_LANG = Locale.getDefault().getLanguage();
private final Map<String, ResourceBundle> resourceBundles = new HashMap<>(); private static final Map<String, ResourceBundle> resourceBundles = new HashMap<>();
private synchronized ResourceBundle getOrLoadResourceBundle(String className, String lang) { public String translate(String className, String lang, String key, Object... args) {
final String bundleKey = className + ":" + lang;
ResourceBundle resourceBundle = resourceBundles.get(bundleKey);
if (resourceBundle != null)
return resourceBundle;
try {
resourceBundle = ResourceBundle.getBundle("i18n." + className, Locale.forLanguageTag(lang));
} catch (MissingResourceException e) {
LOGGER.warn("Can't locate '" + lang + "' translation resource bundle for " + className, e);
return null;
}
resourceBundles.put(bundleKey, resourceBundle);
return resourceBundle;
}
public String translate(final String className, final String key) {
return this.translate(className, DEFAULT_LANG, key);
}
public String translate(final String className, final String lang, final String key, final Object... args) {
ResourceBundle resourceBundle = getOrLoadResourceBundle(className, lang); ResourceBundle resourceBundle = getOrLoadResourceBundle(className, lang);
if (resourceBundle == null || !resourceBundle.containsKey(key)) if (resourceBundle == null || !resourceBundle.containsKey(key))
@ -55,4 +33,37 @@ public enum Translator {
} }
} }
public String translate(String className, String key) {
return this.translate(className, DEFAULT_LANG, key);
}
public Set<String> keySet(String className, String lang) {
ResourceBundle resourceBundle = getOrLoadResourceBundle(className, lang);
if (resourceBundle == null)
return null;
return resourceBundle.keySet();
}
private synchronized ResourceBundle getOrLoadResourceBundle(String className, String lang) {
String bundleKey = className + ":" + lang;
ResourceBundle resourceBundle = resourceBundles.get(bundleKey);
if (resourceBundle != null || resourceBundles.containsKey(bundleKey))
return resourceBundle;
try {
resourceBundle = ResourceBundle.getBundle("i18n." + className, Locale.forLanguageTag(lang));
} catch (MissingResourceException e) {
LOGGER.warn(String.format("Can't locate '%s' translation resource bundle for %s", lang, className));
// Set to null then fall-through to storing in map so we don't emit warning more than once
resourceBundle = null;
}
resourceBundles.put(bundleKey, resourceBundle);
return resourceBundle;
}
} }

View File

@ -1,56 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<localization>
<context locale="de">
<context path="Api">
<context path="BlocksResource">
<!--<context path="GET signature">
<translation key="operation:description" template="returns the block that matches the given signature" />
<translation key="success_response:description" template="the block" />
</context>
<context path="GET first">
<translation key="operation:description" template="returns the genesis block" />
<translation key="success_response:description" template="the block" />
</context>
<context path="GET last">
<translation key="operation:description" template="returns the last valid block" />
<translation key="success_response:description" template="the block" />
</context>
<context path="GET child:signature">
<translation key="operation:description" template="returns the child block of the block that matches the given signature" />
<translation key="success_response:description" template="the block" />
</context>
<context path="GET generatingbalance">
<translation key="operation:description" template="calculates the generating balance of the block that will follow the last block" />
<translation key="success_response:description" template="the generating balance" />
</context>
<context path="GET generatingbalance:signature">
<translation key="operation:description" template="calculates the generating balance of the block that will follow the block that matches the signature" />
<translation key="success_response:description" template="the block" />
</context>
<context path="GET time">
<translation key="operation:description" template="calculates the time it should take for the network to generate the next block" />
<translation key="success_response:description" template="the time" />
</context>
<context path="GET time:generatingbalance">
<translation key="operation:description" template="calculates the time it should take for the network to generate blocks when the current generating balance in the network is the specified generating balance" />
<translation key="success_response:description" template="the time" />
</context>
<context path="GET height">
<translation key="operation:description" template="returns the block height of the last block." />
<translation key="success_response:description" template="the height" />
</context>
<context path="GET height:signature">
<translation key="operation:description" template="returns the block height of the block that matches the given signature" />
<translation key="success_response:description" template="the height" />
</context>
<context path="GET byheight:height">
<translation key="operation:description" template="returns the block whith given height" />
<translation key="success_response:description" template="the block" />
</context>-->
</context>
</context>
</context>
</localization>

View File

@ -1,56 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<localization>
<context locale="en">
<context path="Api">
<context path="BlocksResource">
<context path="GET signature">
<translation key="operation:description" template="returns the block that matches the given signature" />
<translation key="success_response:description" template="the block" />
</context>
<context path="GET first">
<translation key="operation:description" template="returns the genesis block" />
<translation key="success_response:description" template="the block" />
</context>
<context path="GET last">
<translation key="operation:description" template="returns the last valid block" />
<translation key="success_response:description" template="the block" />
</context>
<context path="GET child:signature">
<translation key="operation:description" template="returns the child block of the block that matches the given signature" />
<translation key="success_response:description" template="the block" />
</context>
<context path="GET generatingbalance">
<translation key="operation:description" template="calculates the generating balance of the block that will follow the last block" />
<translation key="success_response:description" template="the generating balance" />
</context>
<context path="GET generatingbalance:signature">
<translation key="operation:description" template="calculates the generating balance of the block that will follow the block that matches the signature" />
<translation key="success_response:description" template="the block" />
</context>
<context path="GET time">
<translation key="operation:description" template="calculates the time it should take for the network to generate the next block" />
<translation key="success_response:description" template="the time" />
</context>
<context path="GET time:generatingbalance">
<translation key="operation:description" template="calculates the time it should take for the network to generate blocks when the current generating balance in the network is the specified generating balance" />
<translation key="success_response:description" template="the time" />
</context>
<context path="GET height">
<translation key="operation:description" template="returns the block height of the last block." />
<translation key="success_response:description" template="the height" />
</context>
<context path="GET height:signature">
<translation key="operation:description" template="returns the block height of the block that matches the given signature" />
<translation key="success_response:description" template="the height" />
</context>
<context path="GET byheight:height">
<translation key="operation:description" template="returns the block whith given height" />
<translation key="success_response:description" template="the block" />
</context>
</context>
</context>
</context>
</localization>

View File

@ -1,72 +1,14 @@
UNKNOWN=Unbekannter Fehler
JSON=JSON Nachricht konnte nicht geparsed werden INVALID_ADDRESS = ung\u00FCltige adresse
NO_BALANCE=Guthaben ungenügend
NOT_YET_RELEASED=Feature wurde noch nicht veröffentlicht INVALID_ASSET_ID = ung\u00FCltige asset ID
INVALID_SIGNATURE=Ungültige Signatur
INVALID_ADDRESS=Ungültige Adresse INVALID_DATA = ung\u00FCltige daten
INVALID_SEED=Ungültiger Seed
INVALID_AMOUNT=Ungültiger Betrag INVALID_PUBLIC_KEY = ung\u00FCltiger public key
INVALID_FEE=Ungültige Gebühr
INVALID_SENDER=Ungültiger Sender INVALID_SIGNATURE = ung\u00FCltige signatur
INVALID_RECIPIENT=Ungültiger Empfänger
INVALID_NAME_LENGTH=Ungültige Namenslänge JSON = JSON nachricht konnte nicht geparsed werden
INVALID_VALUE_LENGTH=Ungültige Wertlänge
INVALID_NAME_OWNER=Ungültiger Namensbesitzer PUBLIC_KEY_NOT_FOUND = public key wurde nicht gefunden
INVALID_BUYER=Ungültiger Käufer
INVALID_PUBLIC_KEY=Ungültiger Public Key
INVALID_OPTIONS_LENGTH=Ungültige Optionen-Länge
INVALID_OPTION_LENGTH=Ungültige Optionslänge
INVALID_DATA=Ungültige Daten
INVALID_DATA_LENGTH=Ungültige Datenlänge
INVALID_UPDATE_VALUE=Ungültiger Update-Wert
KEY_ALREADY_EXISTS=Der Schlüssel existiert bereits, Editieren ist deaktiviert
KEY_NOT_EXISTS=Der Schlüssel existiert nicht
LAST_KEY_IS_DEFAULT_KEY_ERROR=Du kannst den Schlüssel '${key}' nicht löschen, wenn er der einzige ist
FEE_LESS_REQUIRED=fee less required
WALLET_NOT_IN_SYNC=Das Wallet muss synchronisiert werden
INVALID_NETWORK_ADDRESS=Ungültige Netzwerkadresse
WALLET_NO_EXISTS=Das Wallet existiert nicht
WALLET_ADDRESS_NO_EXISTS=Die Adresse existiert nicht im Wallet
WALLET_LOCKED=Das Wallet ist abgeschlossen
WALLET_ALREADY_EXISTS=Das Wallet existiert bereits
WALLET_API_CALL_FORBIDDEN_BY_USER=Der Benutzer hat den API-Aufruf abgelehnt
BLOCK_NO_EXISTS=Der Block existiert nicht
TRANSACTION_NO_EXISTS=Die Transaktion existiert nicht
PUBLIC_KEY_NOT_FOUND=Public Key wurde nicht gefunden
NAME_NO_EXISTS=Der Name existiert nicht
NAME_ALREADY_EXISTS=Der Name existiert bereits
NAME_ALREADY_FOR_SALE=Der Name steht bereits zum Verkauf
NAME_NOT_LOWER_CASE=Der Name muss aus Kleinbuchstaben bestehen
NAME_SALE_NO_EXISTS=Namensverkauf existiert nicht
BUYER_ALREADY_OWNER=Der Käufer ist bereits Besitzer
POLL_NO_EXISTS=Die Abstimmung existiert nicht
POLL_ALREADY_EXISTS=Die Abstimmung existiert bereits
DUPLICATE_OPTION=Nicht alle Optionen sind eindeutig
POLL_OPTION_NO_EXISTS=Die option existiert nicht
ALREADY_VOTED_FOR_THAT_OPTION=Bereits für diese Option abgestimmt
INVALID_ASSET_ID=Ungültige Asset ID
NAME_NOT_REGISTERED=?NAME_NOT_REGISTERED?
NAME_FOR_SALE=?NAME_FOR_SALE?
NAME_WITH_SPACE=?NAME_WITH_SPACE?
INVALID_DESC_LENGTH=Ungültige Beschreibungslänge. Max. Länge ${MAX_LENGTH}
EMPTY_CODE=Der Code ist leer
DATA_SIZE=Ungültige Datenlänge
NULL_PAGES=Ungültige Seiten
INVALID_TYPE_LENGTH=Ungültige Typlänge
INVALID_TAGS_LENGTH=Ungültige Tag-Länge
INVALID_CREATION_BYTES=Fehler in Creation Bytes
BODY_EMPTY=invalid body it must not be empty
BLOG_DISABLED=Dieser Blog ist deaktiviert
NAME_NOT_OWNER=the creator address does not own the author name
TX_AMOUNT=the data size is too large - currently only ${BATCH_TX_AMOUNT} arbitrary transactions are allowed at once!
BLOG_ENTRY_NO_EXISTS=transaction with this signature contains no entries!
BLOG_EMPTY=this blog is empty
POSTID_EMPTY=the attribute postid is empty! this is the signature of the post you want to comment
POST_NOT_EXISTING=for the given postid no blogpost to comment was found
COMMENTING_DISABLED=commenting is for this blog disabled
COMMENT_NOT_EXISTING=for the given signature no comment was found
INVALID_COMMENT_OWNER=invalid comment owner
MESSAGE_FORMAT_NOT_HEX=the Message format is not hex - correct the text or use isTextMessage = true
MESSAGE_BLANK=The message attribute is missing or content is blank
NO_PUBLIC_KEY=The recipient has not yet performed any action in the blockchain.\nYou can't send an encrypted message to him.
MESSAGESIZE_EXCEEDED=Message size exceeded!

View File

@ -1,100 +1,57 @@
#Generated by ResourceBundle Editor (http://essiembre.github.io/eclipse-rbe/)
# Keys are from api.ApiError enum # Keys are from api.ApiError enum
# Common ADDRESS_UNKNOWN = account address unknown
UNKNOWN=unknown error
JSON=failed to parse json message
NO_BALANCE=not enough balance
NOT_YET_RELEASED=that feature is not yet released
UNAUTHORIZED=api call unauthorized
REPOSITORY_ISSUE=repository error
NON_PRODUCTION=This API call is not permitted for production systems
# Validation BLOCKCHAIN_NEEDS_SYNC = blockchain needs to synchronize first
INVALID_SIGNATURE=invalid signature
INVALID_ADDRESS=invalid address
INVALID_SEED=invalid seed
INVALID_AMOUNT=invalid amount
INVALID_FEE=invalid fee
INVALID_SENDER=invalid sender
INVALID_RECIPIENT=invalid recipient
INVALID_NAME_LENGTH=invalid name length
INVALID_VALUE_LENGTH=invalid value length
INVALID_NAME_OWNER=invalid name owner
INVALID_BUYER=invalid buyer
INVALID_PUBLIC_KEY=invalid public key
INVALID_OPTIONS_LENGTH=invalid options length
INVALID_OPTION_LENGTH=invalid option length
INVALID_DATA=invalid data
INVALID_DATA_LENGTH=invalid data length
INVALID_UPDATE_VALUE=invalid update value
KEY_ALREADY_EXISTS=key already exists, edit is false
KEY_NOT_EXISTS=the key does not exist
FEE_LESS_REQUIRED=fee less required
WALLET_NOT_IN_SYNC=wallet needs to be synchronized
INVALID_NETWORK_ADDRESS=invalid network address
ADDRESS_NO_EXISTS=account address does not exist
INVALID_CRITERIA=invalid search criteria
INVALID_REFERENCE=invalid reference
INVALID_PRIVATE_KEY=invalid private key
INVALID_HEIGHT=invalid block height
# Wallet
WALLET_NO_EXISTS=wallet does not exist
WALLET_ADDRESS_NO_EXISTS=address does not exist in wallet
WALLET_LOCKED=wallet is locked
WALLET_ALREADY_EXISTS=wallet already exists
WALLET_API_CALL_FORBIDDEN_BY_USER=wallet denied api call
# Blocks # Blocks
BLOCK_NO_EXISTS=block does not exist BLOCK_UNKNOWN = block unknown
# Transactions CANNOT_MINT = account cannot mint
TRANSACTION_NO_EXISTS=transaction does not exist
PUBLIC_KEY_NOT_FOUND=public key not found
TRANSACTION_INVALID=transaction invalid: %s
# Names GROUP_UNKNOWN = group unknown
NAME_NO_EXISTS=name does not exist
NAME_ALREADY_EXISTS=name already exists
NAME_ALREADY_FOR_SALE=name already for sale
NAME_NOT_LOWER_CASE=name must be lower case
NAME_SALE_NO_EXISTS=namesale does not exist
BUYER_ALREADY_OWNER=buyer is already owner
# Voting INVALID_ADDRESS = invalid address
POLL_NO_EXISTS=poll does not exist
POLL_ALREADY_EXISTS=poll already exists
DUPLICATE_OPTION=not all options are unique
POLL_OPTION_NO_EXISTS=option does not exist
ALREADY_VOTED_FOR_THAT_OPTION=already voted for that option
# Assets # Assets
INVALID_ASSET_ID=invalid asset id INVALID_ASSET_ID = invalid asset id
INVALID_ORDER_ID=invalid asset order id
ORDER_NO_EXISTS=unknown asset order id
# ATs INVALID_CRITERIA = invalid search criteria
EMPTY_CODE=code is empty
DATA_SIZE=invalid data length
NULL_PAGES=invalid pages
INVALID_TYPE_LENGTH=invalid type length
INVALID_TAGS_LENGTH=invalid tags length
INVALID_CREATION_BYTES=error in creation bytes
# Blogs/Name-storage INVALID_DATA = invalid data
BODY_EMPTY=invalid body it must not be empty
BLOG_DISABLED=this blog is disabled
NAME_NOT_OWNER=the creator address does not own the author name
BLOG_ENTRY_NO_EXISTS=transaction with this signature contains no entries!
BLOG_EMPTY=this blog is empty
POSTID_EMPTY=the attribute postid is empty! this is the signature of the post you want to comment
POST_NOT_EXISTING=for the given postid no blogpost to comment was found
COMMENTING_DISABLED=commenting is for this blog disabled
COMMENT_NOT_EXISTING=for the given signature no comment was found
INVALID_COMMENT_OWNER=invalid comment owner
# Messages INVALID_HEIGHT = invalid block height
MESSAGE_FORMAT_NOT_HEX=the Message format is not hex - correct the text or use isTextMessage = true
MESSAGE_BLANK=The message attribute is missing or content is blank INVALID_NETWORK_ADDRESS = invalid network address
NO_PUBLIC_KEY=The recipient has not yet performed any action in the blockchain.\nYou can't send an encrypted message to them.
MESSAGESIZE_EXCEEDED=Message size exceeded! INVALID_ORDER_ID = invalid asset order ID
INVALID_PRIVATE_KEY = invalid private key
INVALID_PUBLIC_KEY = invalid public key
INVALID_REFERENCE = invalid reference
# Validation
INVALID_SIGNATURE = invalid signature
JSON = failed to parse json message
NAME_UNKNOWN = name unknown
NON_PRODUCTION = this API call is not permitted for production systems
ORDER_UNKNOWN = unknown asset order ID
PUBLIC_KEY_NOT_FOUND = public key not found
REPOSITORY_ISSUE = repository error
TRANSACTION_INVALID = transaction invalid: %s
TRANSACTION_UNKNOWN = transaction unknown
TRANSFORMATION_ERROR = could not transform JSON into transaction
UNAUTHORIZED = API call unauthorized

View File

@ -1,100 +0,0 @@
# Keys are from api.ApiError enum
# Common
UNKNOWN=unknown error
JSON=failed to parse json message
NO_BALANCE=not enough balance
NOT_YET_RELEASED=that feature is not yet released
UNAUTHORIZED=api call unauthorized
REPOSITORY_ISSUE=repository error
NON_PRODUCTION=This API call is not permitted for production systems
# Validation
INVALID_SIGNATURE=invalid signature
INVALID_ADDRESS=invalid address
INVALID_SEED=invalid seed
INVALID_AMOUNT=invalid amount
INVALID_FEE=invalid fee
INVALID_SENDER=invalid sender
INVALID_RECIPIENT=invalid recipient
INVALID_NAME_LENGTH=invalid name length
INVALID_VALUE_LENGTH=invalid value length
INVALID_NAME_OWNER=invalid name owner
INVALID_BUYER=invalid buyer
INVALID_PUBLIC_KEY=invalid public key
INVALID_OPTIONS_LENGTH=invalid options length
INVALID_OPTION_LENGTH=invalid option length
INVALID_DATA=invalid data
INVALID_DATA_LENGTH=invalid data length
INVALID_UPDATE_VALUE=invalid update value
KEY_ALREADY_EXISTS=key already exists, edit is false
KEY_NOT_EXISTS=the key does not exist
FEE_LESS_REQUIRED=fee less required
WALLET_NOT_IN_SYNC=wallet needs to be synchronized
INVALID_NETWORK_ADDRESS=invalid network address
ADDRESS_NO_EXISTS=account address does not exist
INVALID_CRITERIA=invalid search criteria
INVALID_REFERENCE=invalid reference
INVALID_PRIVATE_KEY=invalid private key
INVALID_HEIGHT=invalid block height
# Wallet
WALLET_NO_EXISTS=wallet does not exist
WALLET_ADDRESS_NO_EXISTS=address does not exist in wallet
WALLET_LOCKED=wallet is locked
WALLET_ALREADY_EXISTS=wallet already exists
WALLET_API_CALL_FORBIDDEN_BY_USER=wallet denied api call
# Blocks
BLOCK_NO_EXISTS=block does not exist
# Transactions
TRANSACTION_NO_EXISTS=transaction does not exist
PUBLIC_KEY_NOT_FOUND=public key not found
TRANSACTION_INVALID=transaction invalid: %s
# Names
NAME_NO_EXISTS=name does not exist
NAME_ALREADY_EXISTS=name already exists
NAME_ALREADY_FOR_SALE=name already for sale
NAME_NOT_LOWER_CASE=name must be lower case
NAME_SALE_NO_EXISTS=namesale does not exist
BUYER_ALREADY_OWNER=buyer is already owner
# Voting
POLL_NO_EXISTS=poll does not exist
POLL_ALREADY_EXISTS=poll already exists
DUPLICATE_OPTION=not all options are unique
POLL_OPTION_NO_EXISTS=option does not exist
ALREADY_VOTED_FOR_THAT_OPTION=already voted for that option
# Assets
INVALID_ASSET_ID=invalid asset id
INVALID_ORDER_ID=invalid asset order id
ORDER_NO_EXISTS=unknown asset order id
# ATs
EMPTY_CODE=code is empty
DATA_SIZE=invalid data length
NULL_PAGES=invalid pages
INVALID_TYPE_LENGTH=invalid type length
INVALID_TAGS_LENGTH=invalid tags length
INVALID_CREATION_BYTES=error in creation bytes
# Blogs/Name-storage
BODY_EMPTY=invalid body it must not be empty
BLOG_DISABLED=this blog is disabled
NAME_NOT_OWNER=the creator address does not own the author name
BLOG_ENTRY_NO_EXISTS=transaction with this signature contains no entries!
BLOG_EMPTY=this blog is empty
POSTID_EMPTY=the attribute postid is empty! this is the signature of the post you want to comment
POST_NOT_EXISTING=for the given postid no blogpost to comment was found
COMMENTING_DISABLED=commenting is for this blog disabled
COMMENT_NOT_EXISTING=for the given signature no comment was found
INVALID_COMMENT_OWNER=invalid comment owner
# Messages
MESSAGE_FORMAT_NOT_HEX=the Message format is not hex - correct the text or use isTextMessage = true
MESSAGE_BLANK=The message attribute is missing or content is blank
NO_PUBLIC_KEY=The recipient has not yet performed any action in the blockchain.\nYou can't send an encrypted message to them.
MESSAGESIZE_EXCEEDED=Message size exceeded!

View File

@ -1,42 +1,174 @@
OK=OK
INVALID_ADDRESS=INVALID_ADDRESS ACCOUNT_CANNOT_REWARD_SHARE = account cannot reward-share
NEGATIVE_AMOUNT=NEGATIVE_AMOUNT
NEGATIVE_FEE=NEGATIVE_FEE ALREADY_GROUP_ADMIN = already group admin
NO_BALANCE=NO_BALANCE
INVALID_REFERENCE=INVALID_REFERENCE ALREADY_GROUP_MEMBER = already group member
INVALID_NAME_LENGTH=INVALID_NAME_LENGTH
INVALID_VALUE_LENGTH=INVALID_VALUE_LENGTH ALREADY_VOTED_FOR_THAT_OPTION = already voted for that option
NAME_ALREADY_REGISTERED=NAME_ALREADY_REGISTERED
NAME_DOES_NOT_EXIST=NAME_DOES_NOT_EXIST ASSET_ALREADY_EXISTS = asset already exists
INVALID_NAME_OWNER=INVALID_NAME_OWNER
NAME_ALREADY_FOR_SALE=NAME_ALREADY_FOR_SALE ASSET_DOES_NOT_EXIST = ASSET_DOES_NOT_EXIST
NAME_NOT_FOR_SALE=NAME_NOT_FOR_SALE
BUYER_ALREADY_OWNER=BUYER_ALREADY_OWNER ASSET_DOES_NOT_MATCH_AT = ASSET_DOES_NOT_MATCH_AT
INVALID_AMOUNT=INVALID_AMOUNT
INVALID_SELLER=INVALID_SELLER ASSET_NOT_SPENDABLE = ASSET_NOT_SPENDABLE
NAME_NOT_LOWER_CASE=NAME_NOT_LOWER_CASE
INVALID_DESCRIPTION_LENGTH=INVALID_DESCRIPTION_LENGTH AT_ALREADY_EXISTS = AT_ALREADY_EXISTS
INVALID_OPTIONS_COUNT=INVALID_OPTIONS_COUNT
INVALID_OPTION_LENGTH=INVALID_OPTION_LENGTH AT_IS_FINISHED = AT_IS_FINISHED
DUPLICATE_OPTION=DUPLICATE_OPTION
POLL_ALREADY_EXISTS=POLL_ALREADY_EXISTS AT_UNKNOWN = AT_UNKNOWN
POLL_DOES_NOT_EXIST=POLL_DOES_NOT_EXIST
POLL_OPTION_DOES_NOT_EXIST=POLL_OPTION_DOES_NOT_EXIST BANNED_FROM_GROUP = BANNED_FROM_GROUP
ALREADY_VOTED_FOR_THAT_OPTION=ALREADY_VOTED_FOR_THAT_OPTION
INVALID_DATA_LENGTH=INVALID_DATA_LENGTH BAN_EXISTS = BAN_EXISTS
INVALID_QUANTITY=INVALID_QUANTITY
ASSET_DOES_NOT_EXIST=ASSET_DOES_NOT_EXIST BAN_UNKNOWN = BAN_UNKNOWN
INVALID_RETURN=INVALID_RETURN
HAVE_EQUALS_WANT=HAVE_EQUALS_WANT BUYER_ALREADY_OWNER = BUYER_ALREADY_OWNER
ORDER_DOES_NOT_EXIST=ORDER_DOES_NOT_EXIST
INVALID_ORDER_CREATOR=INVALID_ORDER_CREATOR CLOCK_NOT_SYNCED = CLOCK_NOT_SYNCED
INVALID_PAYMENTS_COUNT=INVALID_PAYMENTS_COUNT
NEGATIVE_PRICE=NEGATIVE_PRICE DUPLICATE_OPTION = DUPLICATE_OPTION
INVALID_CREATION_BYTES=INVALID_CREATION_BYTES
INVALID_TAGS_LENGTH=INVALID_TAGS_LENGTH GROUP_ALREADY_EXISTS = GROUP_ALREADY_EXISTS
INVALID_AT_TYPE_LENGTH=INVALID_AT_TYPE_LENGTH
INVALID_AT_TRANSACTION=INVALID_AT_TRANSACTION GROUP_APPROVAL_DECIDED = GROUP_APPROVAL_DECIDED
AT_IS_FINISHED=AT_IS_FINISHED
ASSET_DOES_NOT_MATCH_AT=ASSET_DOES_NOT_MATCH_AT GROUP_APPROVAL_NOT_REQUIRED = GROUP_APPROVAL_NOT_REQUIRED
ASSET_ALREADY_EXISTS=ASSET_ALREADY_EXISTS
NOT_YET_RELEASED=NOT_YET_RELEASED GROUP_DOES_NOT_EXIST = GROUP_DOES_NOT_EXIST
GROUP_ID_MISMATCH = GROUP_ID_MISMATCH
GROUP_OWNER_CANNOT_LEAVE = GROUP_OWNER_CANNOT_LEAVE
HAVE_EQUALS_WANT = HAVE_EQUALS_WANT
INSUFFICIENT_FEE = INSUFFICIENT_FEE
INVALID_ADDRESS = INVALID_ADDRESS
INVALID_AMOUNT = INVALID_AMOUNT
INVALID_ASSET_OWNER = INVALID_ASSET_OWNER
INVALID_AT_TRANSACTION = INVALID_AT_TRANSACTION
INVALID_AT_TYPE_LENGTH = INVALID_AT_TYPE_LENGTH
INVALID_CREATION_BYTES = INVALID_CREATION_BYTES
INVALID_DATA_LENGTH = INVALID_DATA_LENGTH
INVALID_DESCRIPTION_LENGTH = INVALID_DESCRIPTION_LENGTH
INVALID_GROUP_APPROVAL_THRESHOLD = INVALID_GROUP_APPROVAL_THRESHOLD
INVALID_GROUP_ID = INVALID_GROUP_ID
INVALID_GROUP_OWNER = INVALID_GROUP_OWNER
INVALID_LIFETIME = INVALID_LIFETIME
INVALID_NAME_LENGTH = INVALID_NAME_LENGTH
INVALID_NAME_OWNER = INVALID_NAME_OWNER
INVALID_OPTIONS_COUNT = INVALID_OPTIONS_COUNT
INVALID_OPTION_LENGTH = INVALID_OPTION_LENGTH
INVALID_ORDER_CREATOR = INVALID_ORDER_CREATOR
INVALID_PAYMENTS_COUNT = INVALID_PAYMENTS_COUNT
INVALID_PUBLIC_KEY = INVALID_PUBLIC_KEY
INVALID_QUANTITY = INVALID_QUANTITY
INVALID_REFERENCE = INVALID_REFERENCE
INVALID_RETURN = INVALID_RETURN
INVALID_REWARD_SHARE_PERCENT = INVALID_REWARD_SHARE_PERCENT
INVALID_SELLER = INVALID_SELLER
INVALID_TAGS_LENGTH = INVALID_TAGS_LENGTH
INVALID_TX_GROUP_ID = INVALID_TX_GROUP_ID
INVALID_VALUE_LENGTH = INVALID_VALUE_LENGTH
INVITE_UNKNOWN = INVITE_UNKNOWN
JOIN_REQUEST_EXISTS = JOIN_REQUEST_EXISTS
MAXIMUM_REWARD_SHARES = MAXIMUM_REWARD_SHARES
MISSING_CREATOR = MISSING_CREATOR
MULTIPLE_NAMES_FORBIDDEN = MULTIPLE_NAMES_FORBIDDEN
NAME_ALREADY_FOR_SALE = NAME_ALREADY_FOR_SALE
NAME_ALREADY_REGISTERED = NAME_ALREADY_REGISTERED
NAME_DOES_NOT_EXIST = NAME_DOES_NOT_EXIST
NAME_NOT_FOR_SALE = NAME_NOT_FOR_SALE
NAME_NOT_LOWER_CASE = NAME_NOT_LOWER_CASE
NEGATIVE_AMOUNT = NEGATIVE_AMOUNT
NEGATIVE_FEE = NEGATIVE_FEE
NEGATIVE_PRICE = NEGATIVE_PRICE
NOT_GROUP_ADMIN = NOT_GROUP_ADMIN
NOT_GROUP_MEMBER = NOT_GROUP_MEMBER
NOT_MINTING_ACCOUNT = NOT_MINTING_ACCOUNT
NOT_YET_RELEASED = NOT_YET_RELEASED
NO_BALANCE = NO_BALANCE
NO_BLOCKCHAIN_LOCK = NO_BLOCKCHAIN_LOCK
NO_FLAG_PERMISSION = NO_FLAG_PERMISSION
OK = OK
ORDER_ALREADY_CLOSED = ORDER_ALREADY_CLOSED
ORDER_DOES_NOT_EXIST = ORDER_DOES_NOT_EXIST
POLL_ALREADY_EXISTS = POLL_ALREADY_EXISTS
POLL_DOES_NOT_EXIST = POLL_DOES_NOT_EXIST
POLL_OPTION_DOES_NOT_EXIST = POLL_OPTION_DOES_NOT_EXIST
PUBLIC_KEY_UNKNOWN = PUBLIC_KEY_UNKNOWN
SELF_SHARE_EXISTS = SELF_SHARE_EXISTS
TIMESTAMP_TOO_NEW = TIMESTAMP_TOO_NEW
TIMESTAMP_TOO_OLD = TIMESTAMP_TOO_OLD
TOO_MANY_UNCONFIRMED = TOO_MANY_UNCONFIRMED
TRANSACTION_ALREADY_CONFIRMED = TRANSACTION_ALREADY_CONFIRMED
TRANSACTION_ALREADY_EXISTS = TRANSACTION_ALREADY_EXISTS
TRANSACTION_UNKNOWN = TRANSACTION_UNKNOWN
TX_GROUP_ID_MISMATCH = TX_GROUP_ID_MISMATCH

View File

@ -94,7 +94,7 @@ public class AssetsApiTests extends ApiCommon {
try { try {
assertNotNull(this.assetsResource.getAssetOrder(FAKE_ORDER_ID_BASE58)); assertNotNull(this.assetsResource.getAssetOrder(FAKE_ORDER_ID_BASE58));
} catch (ApiException e) { } catch (ApiException e) {
assertTrue(e.error == ApiError.ORDER_NO_EXISTS.getCode()); assertTrue(e.error == ApiError.ORDER_UNKNOWN.getCode());
} }
} }
@ -103,13 +103,13 @@ public class AssetsApiTests extends ApiCommon {
try { try {
assertNotNull(this.assetsResource.getAssetOrderTrades(FAKE_ORDER_ID_BASE58, null, null, null)); assertNotNull(this.assetsResource.getAssetOrderTrades(FAKE_ORDER_ID_BASE58, null, null, null));
} catch (ApiException e) { } catch (ApiException e) {
assertTrue(e.error == ApiError.ORDER_NO_EXISTS.getCode()); assertTrue(e.error == ApiError.ORDER_UNKNOWN.getCode());
} }
try { try {
assertNotNull(this.assetsResource.getAssetOrderTrades(FAKE_ORDER_ID_BASE58, 1, 1, true)); assertNotNull(this.assetsResource.getAssetOrderTrades(FAKE_ORDER_ID_BASE58, 1, 1, true));
} catch (ApiException e) { } catch (ApiException e) {
assertTrue(e.error == ApiError.ORDER_NO_EXISTS.getCode()); assertTrue(e.error == ApiError.ORDER_UNKNOWN.getCode());
} }
} }

View File

@ -0,0 +1,58 @@
package org.qortal.test.apps;
import java.util.Arrays;
import java.util.Collections;
import java.util.Locale;
import java.util.Set;
import java.util.stream.Collectors;
import org.qortal.api.ApiError;
import org.qortal.globalization.Translator;
import org.qortal.transaction.Transaction.ValidationResult;
public class CheckTranslations {
private static final String[] SUPPORTED_LANGS = new String[] { "en", "de", "zh", "ru" };
private static final Set<String> SYSTRAY_KEYS = Set.of("BLOCK_HEIGHT", "CHECK_TIME_ACCURACY", "CONNECTION", "CONNECTIONS",
"EXIT", "MINTING_DISABLED", "MINTING_ENABLED", "OPEN_NODE_UI", "SYNCHRONIZE_CLOCK", "SYNCHRONIZING_CLOCK");
private static String failurePrefix;
public static void main(String[] args) {
for (String lang : SUPPORTED_LANGS) {
System.out.println(String.format("\n# Checking '%s' translations", lang));
Locale.setDefault(Locale.forLanguageTag(lang));
failurePrefix = "!!" + lang + ":";
checkTranslations("TransactionValidity", lang, Arrays.stream(ValidationResult.values()).map(value -> value.name()).collect(Collectors.toSet()));
checkTranslations("ApiError", lang, Arrays.stream(ApiError.values()).map(value -> value.name()).collect(Collectors.toSet()));
checkTranslations("SysTray", lang, SYSTRAY_KEYS);
}
}
private static void checkTranslations(String className, String lang, Set<String> keys) {
System.out.println(String.format("## Checking '%s' translations for %s", lang, className));
Set<String> allKeys = Translator.INSTANCE.keySet(className, lang);
if (allKeys == null) {
System.out.println(String.format("NO '%s' translations for %s!", lang, className));
allKeys = Collections.emptySet();
}
for (String key : keys) {
allKeys.remove(key);
String translation = Translator.INSTANCE.translate(className, lang, key);
if (translation.startsWith(failurePrefix))
System.out.println(String.format("Missing key '%s' in %s_%s.properties", key, className, lang));
}
// Any leftover keys?
for (String key : allKeys)
System.out.println(String.format("Extraneous key '%s' in %s_%s.properties", key, className, lang));
}
}