diff --git a/src/main/java/org/qortal/api/ApiError.java b/src/main/java/org/qortal/api/ApiError.java index 91257515..f4cfdfb5 100644 --- a/src/main/java/org/qortal/api/ApiError.java +++ b/src/main/java/org/qortal/api/ApiError.java @@ -7,10 +7,10 @@ import java.util.Map; public enum ApiError { // COMMON - UNKNOWN(0, 500), + // UNKNOWN(0, 500), JSON(1, 400), - NO_BALANCE(2, 422), - NOT_YET_RELEASED(3, 422), + // NO_BALANCE(2, 422), + // NOT_YET_RELEASED(3, 422), UNAUTHORIZED(4, 403), REPOSITORY_ISSUE(5, 500), NON_PRODUCTION(6, 403), @@ -19,28 +19,28 @@ public enum ApiError { // VALIDATION INVALID_SIGNATURE(101, 400), INVALID_ADDRESS(102, 400), - INVALID_SEED(103, 400), - INVALID_AMOUNT(104, 400), - INVALID_FEE(105, 400), - INVALID_SENDER(106, 400), - INVALID_RECIPIENT(107, 400), - INVALID_NAME_LENGTH(108, 400), - INVALID_VALUE_LENGTH(109, 400), - INVALID_NAME_OWNER(110, 400), - INVALID_BUYER(111, 400), + // INVALID_SEED(103, 400), + // INVALID_AMOUNT(104, 400), + // INVALID_FEE(105, 400), + // INVALID_SENDER(106, 400), + // INVALID_RECIPIENT(107, 400), + // INVALID_NAME_LENGTH(108, 400), + // INVALID_VALUE_LENGTH(109, 400), + // INVALID_NAME_OWNER(110, 400), + // INVALID_BUYER(111, 400), INVALID_PUBLIC_KEY(112, 400), - INVALID_OPTIONS_LENGTH(113, 400), - INVALID_OPTION_LENGTH(114, 400), + // INVALID_OPTIONS_LENGTH(113, 400), + // INVALID_OPTION_LENGTH(114, 400), INVALID_DATA(115, 400), - INVALID_DATA_LENGTH(116, 400), - INVALID_UPDATE_VALUE(117, 400), - KEY_ALREADY_EXISTS(118, 422), - KEY_NOT_EXISTS(119, 404), - LAST_KEY_IS_DEFAULT_KEY_ERROR(120, 422), - FEE_LESS_REQUIRED(121, 422), - WALLET_NOT_IN_SYNC(122, 422), + // INVALID_DATA_LENGTH(116, 400), + // INVALID_UPDATE_VALUE(117, 400), + // KEY_ALREADY_EXISTS(118, 422), + // KEY_NOT_EXISTS(119, 404), + // LAST_KEY_IS_DEFAULT_KEY_ERROR(120, 422), + // FEE_LESS_REQUIRED(121, 422), + // WALLET_NOT_IN_SYNC(122, 422), INVALID_NETWORK_ADDRESS(123, 404), - ADDRESS_NO_EXISTS(124, 404), + ADDRESS_UNKNOWN(124, 404), INVALID_CRITERIA(125, 400), INVALID_REFERENCE(126, 400), TRANSFORMATION_ERROR(127, 400), @@ -49,72 +49,72 @@ public enum ApiError { CANNOT_MINT(130, 400), // WALLET - WALLET_NO_EXISTS(201, 404), - WALLET_ADDRESS_NO_EXISTS(202, 404), - WALLET_LOCKED(203, 422), - WALLET_ALREADY_EXISTS(204, 422), - WALLET_API_CALL_FORBIDDEN_BY_USER(205, 403), + // WALLET_NO_EXISTS(201, 404), + // WALLET_ADDRESS_NO_EXISTS(202, 404), + // WALLET_LOCKED(203, 422), + // WALLET_ALREADY_EXISTS(204, 422), + // WALLET_API_CALL_FORBIDDEN_BY_USER(205, 403), // BLOCKS - BLOCK_NO_EXISTS(301, 404), + BLOCK_UNKNOWN(301, 404), // TRANSACTIONS - TRANSACTION_NO_EXISTS(311, 404), + TRANSACTION_UNKNOWN(311, 404), PUBLIC_KEY_NOT_FOUND(304, 404), TRANSACTION_INVALID(312, 400), // NAMING - NAME_NO_EXISTS(401, 404), - NAME_ALREADY_EXISTS(402, 422), - NAME_ALREADY_FOR_SALE(403, 422), - NAME_NOT_LOWER_CASE(404, 422), - NAME_SALE_NO_EXISTS(410, 404), - BUYER_ALREADY_OWNER(411, 422), + NAME_UNKNOWN(401, 404), + // NAME_ALREADY_EXISTS(402, 422), + // NAME_ALREADY_FOR_SALE(403, 422), + // NAME_NOT_LOWER_CASE(404, 422), + // NAME_SALE_NO_EXISTS(410, 404), + // BUYER_ALREADY_OWNER(411, 422), // POLLS - POLL_NO_EXISTS(501, 404), - POLL_ALREADY_EXISTS(502, 422), - DUPLICATE_OPTION(503, 422), - POLL_OPTION_NO_EXISTS(504, 404), - ALREADY_VOTED_FOR_THAT_OPTION(505, 422), + // POLL_NO_EXISTS(501, 404), + // POLL_ALREADY_EXISTS(502, 422), + // DUPLICATE_OPTION(503, 422), + // POLL_OPTION_NO_EXISTS(504, 404), + // ALREADY_VOTED_FOR_THAT_OPTION(505, 422), // ASSET INVALID_ASSET_ID(601, 400), INVALID_ORDER_ID(602, 400), - ORDER_NO_EXISTS(603, 404), + ORDER_UNKNOWN(603, 404), // NAME PAYMENTS - NAME_NOT_REGISTERED(701, 422), - NAME_FOR_SALE(702, 422), - NAME_WITH_SPACE(703, 422), + // NAME_NOT_REGISTERED(701, 422), + // NAME_FOR_SALE(702, 422), + // NAME_WITH_SPACE(703, 422), // ATs - INVALID_DESC_LENGTH(801, 400), - EMPTY_CODE(802, 400), - DATA_SIZE(803, 400), - NULL_PAGES(804, 400), - INVALID_TYPE_LENGTH(805, 400), - INVALID_TAGS_LENGTH(806, 400), - INVALID_CREATION_BYTES(809, 400), + // INVALID_DESC_LENGTH(801, 400), + // EMPTY_CODE(802, 400), + // DATA_SIZE(803, 400), + // NULL_PAGES(804, 400), + // INVALID_TYPE_LENGTH(805, 400), + // INVALID_TAGS_LENGTH(806, 400), + // INVALID_CREATION_BYTES(809, 400), // BLOG/Namestorage - BODY_EMPTY(901, 400), - BLOG_DISABLED(902, 403), - NAME_NOT_OWNER(903, 422), - TX_AMOUNT(904, 400), - BLOG_ENTRY_NO_EXISTS(905, 404), - BLOG_EMPTY(906, 404), - POSTID_EMPTY(907, 400), - POST_NOT_EXISTING(908, 404), - COMMENTING_DISABLED(909, 403), - COMMENT_NOT_EXISTING(910, 404), - INVALID_COMMENT_OWNER(911, 422), + // BODY_EMPTY(901, 400), + // BLOG_DISABLED(902, 403), + // NAME_NOT_OWNER(903, 422), + // TX_AMOUNT(904, 400), + // BLOG_ENTRY_NO_EXISTS(905, 404), + // BLOG_EMPTY(906, 404), + // POSTID_EMPTY(907, 400), + // POST_NOT_EXISTING(908, 404), + // COMMENTING_DISABLED(909, 403), + // COMMENT_NOT_EXISTING(910, 404), + // INVALID_COMMENT_OWNER(911, 422), // Messages - MESSAGE_FORMAT_NOT_HEX(1001, 400), - MESSAGE_BLANK(1002, 400), - NO_PUBLIC_KEY(1003, 422), - MESSAGESIZE_EXCEEDED(1004, 400), + // MESSAGE_FORMAT_NOT_HEX(1001, 400), + // MESSAGE_BLANK(1002, 400), + // NO_PUBLIC_KEY(1003, 422), + // MESSAGESIZE_EXCEEDED(1004, 400), // Groups GROUP_UNKNOWN(1101, 404); diff --git a/src/main/java/org/qortal/api/resource/AssetsResource.java b/src/main/java/org/qortal/api/resource/AssetsResource.java index 0cf97899..8af91e45 100644 --- a/src/main/java/org/qortal/api/resource/AssetsResource.java +++ b/src/main/java/org/qortal/api/resource/AssetsResource.java @@ -410,7 +410,7 @@ public class AssetsResource { } ) @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) { // Decode orderID @@ -424,7 +424,7 @@ public class AssetsResource { try (final Repository repository = RepositoryManager.getRepository()) { OrderData orderData = repository.getAssetRepository().fromOrderId(orderId); if (orderData == null) - throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.ORDER_NO_EXISTS); + throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.ORDER_UNKNOWN); return orderData; } catch (DataException e) { @@ -451,7 +451,7 @@ public class AssetsResource { } ) @ApiErrors({ - ApiError.INVALID_ORDER_ID, ApiError.ORDER_NO_EXISTS, ApiError.REPOSITORY_ISSUE + ApiError.INVALID_ORDER_ID, ApiError.ORDER_UNKNOWN, ApiError.REPOSITORY_ISSUE }) public List getAssetOrderTrades(@PathParam("orderid") String orderId58, @Parameter( ref = "limit" @@ -471,7 +471,7 @@ public class AssetsResource { try (final Repository repository = RepositoryManager.getRepository()) { OrderData orderData = repository.getAssetRepository().fromOrderId(orderId); 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); } catch (DataException e) { @@ -497,7 +497,7 @@ public class AssetsResource { } ) @ApiErrors({ - ApiError.INVALID_ADDRESS, ApiError.ADDRESS_NO_EXISTS, ApiError.REPOSITORY_ISSUE + ApiError.INVALID_ADDRESS, ApiError.ADDRESS_UNKNOWN, ApiError.REPOSITORY_ISSUE }) public List getAccountOrders(@PathParam("address") String address, @QueryParam("includeClosed") boolean includeClosed, @QueryParam("includeFulfilled") boolean includeFulfilled, @Parameter( @@ -514,11 +514,11 @@ public class AssetsResource { AccountData accountData = repository.getAccountRepository().getAccount(address); if (accountData == null) - throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.ADDRESS_NO_EXISTS); + throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.ADDRESS_UNKNOWN); byte[] publicKey = accountData.getPublicKey(); 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); } catch (ApiException e) { @@ -546,7 +546,7 @@ public class AssetsResource { } ) @ApiErrors({ - ApiError.INVALID_ADDRESS, ApiError.ADDRESS_NO_EXISTS, ApiError.REPOSITORY_ISSUE + ApiError.INVALID_ADDRESS, ApiError.ADDRESS_UNKNOWN, ApiError.REPOSITORY_ISSUE }) public List getAccountAssetPairOrders(@PathParam("address") String address, @PathParam("assetid") int assetId, @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); if (accountData == null) - throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.ADDRESS_NO_EXISTS); + throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.ADDRESS_UNKNOWN); byte[] publicKey = accountData.getPublicKey(); 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)) throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_ASSET_ID); diff --git a/src/main/java/org/qortal/api/resource/BlocksResource.java b/src/main/java/org/qortal/api/resource/BlocksResource.java index 10264a37..5bd73cfe 100644 --- a/src/main/java/org/qortal/api/resource/BlocksResource.java +++ b/src/main/java/org/qortal/api/resource/BlocksResource.java @@ -59,7 +59,7 @@ public class BlocksResource { } ) @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) { // Decode signature @@ -98,7 +98,7 @@ public class BlocksResource { } ) @ApiErrors({ - ApiError.INVALID_SIGNATURE, ApiError.BLOCK_NO_EXISTS, ApiError.REPOSITORY_ISSUE + ApiError.INVALID_SIGNATURE, ApiError.BLOCK_UNKNOWN, ApiError.REPOSITORY_ISSUE }) public List getBlockTransactions(@PathParam("signature") String signature58, @Parameter( ref = "limit" @@ -117,7 +117,7 @@ public class BlocksResource { try (final Repository repository = RepositoryManager.getRepository()) { 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); } catch (ApiException e) { @@ -144,13 +144,11 @@ public class BlocksResource { } ) @ApiErrors({ - ApiError.BLOCK_NO_EXISTS, ApiError.REPOSITORY_ISSUE + ApiError.REPOSITORY_ISSUE }) public BlockData getFirstBlock() { try (final Repository repository = RepositoryManager.getRepository()) { return repository.getBlockRepository().fromHeight(1); - } catch (ApiException e) { - throw e; } catch (DataException e) { throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e); } @@ -173,13 +171,11 @@ public class BlocksResource { } ) @ApiErrors({ - ApiError.BLOCK_NO_EXISTS, ApiError.REPOSITORY_ISSUE + ApiError.REPOSITORY_ISSUE }) public BlockData getLastBlock() { try (final Repository repository = RepositoryManager.getRepository()) { return repository.getBlockRepository().getLastBlock(); - } catch (ApiException e) { - throw e; } catch (DataException e) { throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e); } @@ -202,7 +198,7 @@ public class BlocksResource { } ) @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) { // Decode signature @@ -218,13 +214,13 @@ public class BlocksResource { // Check block exists 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); // Check child block exists if (childBlockData == null) - throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.BLOCK_NO_EXISTS); + throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.BLOCK_UNKNOWN); return childBlockData; } catch (ApiException e) { @@ -282,7 +278,7 @@ public class BlocksResource { } ) @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) { // Decode signature @@ -298,7 +294,7 @@ public class BlocksResource { // Check block exists if (blockData == null) - throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.BLOCK_NO_EXISTS); + throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.BLOCK_UNKNOWN); return blockData.getHeight(); } catch (ApiException e) { @@ -325,13 +321,13 @@ public class BlocksResource { } ) @ApiErrors({ - ApiError.BLOCK_NO_EXISTS, ApiError.REPOSITORY_ISSUE + ApiError.BLOCK_UNKNOWN, ApiError.REPOSITORY_ISSUE }) public BlockData getByHeight(@PathParam("height") int height) { try (final Repository repository = RepositoryManager.getRepository()) { BlockData blockData = repository.getBlockRepository().fromHeight(height); if (blockData == null) - throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.BLOCK_NO_EXISTS); + throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.BLOCK_UNKNOWN); return blockData; } catch (ApiException e) { @@ -357,17 +353,17 @@ public class BlocksResource { } ) @ApiErrors({ - ApiError.BLOCK_NO_EXISTS, ApiError.REPOSITORY_ISSUE + ApiError.BLOCK_UNKNOWN, ApiError.REPOSITORY_ISSUE }) public BlockData getByTimestamp(@PathParam("timestamp") long timestamp) { try (final Repository repository = RepositoryManager.getRepository()) { int height = repository.getBlockRepository().getHeightFromTimestamp(timestamp); 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); if (blockData == null) - throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.BLOCK_NO_EXISTS); + throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.BLOCK_UNKNOWN); return blockData; } catch (ApiException e) { @@ -396,7 +392,7 @@ public class BlocksResource { } ) @ApiErrors({ - ApiError.BLOCK_NO_EXISTS, ApiError.REPOSITORY_ISSUE + ApiError.REPOSITORY_ISSUE }) public List getBlockRange(@PathParam("height") int height, @Parameter( ref = "count" @@ -414,8 +410,6 @@ public class BlocksResource { } return blocks; - } catch (ApiException e) { - throw e; } catch (DataException e) { throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e); } diff --git a/src/main/java/org/qortal/api/resource/NamesResource.java b/src/main/java/org/qortal/api/resource/NamesResource.java index 2497c716..e380ab55 100644 --- a/src/main/java/org/qortal/api/resource/NamesResource.java +++ b/src/main/java/org/qortal/api/resource/NamesResource.java @@ -23,6 +23,7 @@ import javax.ws.rs.core.MediaType; import org.qortal.api.ApiError; import org.qortal.api.ApiErrors; +import org.qortal.api.ApiException; import org.qortal.api.ApiExceptionFactory; import org.qortal.api.model.NameSummary; 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) { 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) { throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e); } diff --git a/src/main/java/org/qortal/api/resource/PeersResource.java b/src/main/java/org/qortal/api/resource/PeersResource.java index 1afdbb41..d019bb4f 100644 --- a/src/main/java/org/qortal/api/resource/PeersResource.java +++ b/src/main/java/org/qortal/api/resource/PeersResource.java @@ -137,7 +137,7 @@ public class PeersResource { } ) @ApiErrors({ - ApiError.INVALID_DATA, ApiError.REPOSITORY_ISSUE + ApiError.INVALID_NETWORK_ADDRESS, ApiError.REPOSITORY_ISSUE }) public String addPeer(String address) { Security.checkApiCallAllowed(request); @@ -151,7 +151,7 @@ public class PeersResource { return "true"; } catch (IllegalArgumentException e) { - throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_DATA); + throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_NETWORK_ADDRESS); } catch (ApiException e) { throw e; } catch (DataException e) { @@ -188,7 +188,7 @@ public class PeersResource { } ) @ApiErrors({ - ApiError.INVALID_DATA, ApiError.REPOSITORY_ISSUE + ApiError.INVALID_NETWORK_ADDRESS, ApiError.REPOSITORY_ISSUE }) public String removePeer(String address) { Security.checkApiCallAllowed(request); @@ -199,7 +199,7 @@ public class PeersResource { boolean wasKnown = Network.getInstance().forgetPeer(peerAddress); return wasKnown ? "true" : "false"; } catch (IllegalArgumentException e) { - throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_DATA); + throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_NETWORK_ADDRESS); } catch (ApiException e) { throw e; } catch (DataException e) { @@ -223,7 +223,7 @@ public class PeersResource { } ) @ApiErrors({ - ApiError.INVALID_DATA, ApiError.REPOSITORY_ISSUE + ApiError.REPOSITORY_ISSUE }) public String removeKnownPeers(String address) { Security.checkApiCallAllowed(request); @@ -232,8 +232,6 @@ public class PeersResource { int numDeleted = Network.getInstance().forgetAllPeers(); return numDeleted != 0 ? "true" : "false"; - } catch (ApiException e) { - throw e; } catch (DataException e) { throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e); } diff --git a/src/main/java/org/qortal/api/resource/TransactionsResource.java b/src/main/java/org/qortal/api/resource/TransactionsResource.java index 22920af9..292d7f50 100644 --- a/src/main/java/org/qortal/api/resource/TransactionsResource.java +++ b/src/main/java/org/qortal/api/resource/TransactionsResource.java @@ -69,7 +69,7 @@ public class TransactionsResource { } ) @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) { byte[] signature; @@ -82,7 +82,7 @@ public class TransactionsResource { try (final Repository repository = RepositoryManager.getRepository()) { TransactionData transactionData = repository.getTransactionRepository().fromSignature(signature); if (transactionData == null) - throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.TRANSACTION_NO_EXISTS); + throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.TRANSACTION_UNKNOWN); return transactionData; } catch (ApiException e) { @@ -110,7 +110,7 @@ public class TransactionsResource { } ) @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) { byte[] signature; @@ -123,7 +123,7 @@ public class TransactionsResource { try (final Repository repository = RepositoryManager.getRepository()) { TransactionData transactionData = repository.getTransactionRepository().fromSignature(signature); 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); @@ -154,7 +154,7 @@ public class TransactionsResource { } ) @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) { byte[] reference; @@ -167,7 +167,7 @@ public class TransactionsResource { try (final Repository repository = RepositoryManager.getRepository()) { TransactionData transactionData = repository.getTransactionRepository().fromReference(reference); if (transactionData == null) - throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.TRANSACTION_NO_EXISTS); + throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.TRANSACTION_UNKNOWN); return transactionData; } catch (ApiException e) { @@ -196,7 +196,7 @@ public class TransactionsResource { } ) @ApiErrors({ - ApiError.INVALID_SIGNATURE, ApiError.BLOCK_NO_EXISTS, ApiError.REPOSITORY_ISSUE + ApiError.INVALID_SIGNATURE, ApiError.BLOCK_UNKNOWN, ApiError.REPOSITORY_ISSUE }) public List getBlockTransactions(@PathParam("signature") String signature58, @Parameter( ref = "limit" @@ -215,7 +215,7 @@ public class TransactionsResource { try (final Repository repository = RepositoryManager.getRepository()) { 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); } catch (ApiException e) { diff --git a/src/main/java/org/qortal/globalization/BIP39WordList.java b/src/main/java/org/qortal/globalization/BIP39WordList.java index f5228b2c..3f1c7a11 100644 --- a/src/main/java/org/qortal/globalization/BIP39WordList.java +++ b/src/main/java/org/qortal/globalization/BIP39WordList.java @@ -17,36 +17,32 @@ import org.apache.logging.log4j.Logger; public enum BIP39WordList { INSTANCE; - private Logger LOGGER = LogManager.getLogger(BIP39WordList.class); + private static final Logger LOGGER = LogManager.getLogger(BIP39WordList.class); - private Map> wordListsByLang; - - private BIP39WordList() { - wordListsByLang = new HashMap<>(); - } + private static final Map> wordListsByLang = new HashMap<>(); public synchronized List getByLang(String lang) { List wordList = wordListsByLang.get(lang); - if (wordList == null) { + if (wordList == null && !wordListsByLang.containsKey(lang)) { ClassLoader loader = this.getClass().getClassLoader(); 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)); - return null; - } wordList = new BufferedReader(new InputStreamReader(inputStream)).lines().collect(Collectors.toList()); } catch (IOException e) { - LOGGER.warn(String.format("Error reading '%s' BIP39 wordlist", lang), e); - return null; + LOGGER.warn(String.format("Error reading '%s' BIP39 wordlist: %s", lang, e.getMessage())); } wordListsByLang.put(lang, wordList); } - return Collections.unmodifiableList(wordList); + if (wordList != null) + return Collections.unmodifiableList(wordList); + else + return null; } } diff --git a/src/main/java/org/qortal/globalization/Translator.java b/src/main/java/org/qortal/globalization/Translator.java index 955f95cb..8f0b6136 100644 --- a/src/main/java/org/qortal/globalization/Translator.java +++ b/src/main/java/org/qortal/globalization/Translator.java @@ -6,6 +6,7 @@ import java.util.Map; import java.util.MissingFormatArgumentException; import java.util.MissingResourceException; import java.util.ResourceBundle; +import java.util.Set; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -13,35 +14,12 @@ import org.apache.logging.log4j.Logger; public enum Translator { INSTANCE; - private final Logger LOGGER = LogManager.getLogger(Translator.class); - private final String DEFAULT_LANG = Locale.getDefault().getLanguage(); + private static final Logger LOGGER = LogManager.getLogger(Translator.class); + private static final String DEFAULT_LANG = Locale.getDefault().getLanguage(); - private final Map resourceBundles = new HashMap<>(); + private static final Map resourceBundles = new HashMap<>(); - private synchronized ResourceBundle getOrLoadResourceBundle(String className, String lang) { - 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) { + public String translate(String className, String lang, String key, Object... args) { ResourceBundle resourceBundle = getOrLoadResourceBundle(className, lang); 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 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; + } + } diff --git a/src/main/resources/globalization/BlocksResource.de.xml b/src/main/resources/globalization/BlocksResource.de.xml deleted file mode 100644 index b9610a74..00000000 --- a/src/main/resources/globalization/BlocksResource.de.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - - - diff --git a/src/main/resources/globalization/BlocksResource.en.xml b/src/main/resources/globalization/BlocksResource.en.xml deleted file mode 100644 index b87b35af..00000000 --- a/src/main/resources/globalization/BlocksResource.en.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/i18n/ApiError_de.properties b/src/main/resources/i18n/ApiError_de.properties index 84b9f00d..b2825e0d 100644 --- a/src/main/resources/i18n/ApiError_de.properties +++ b/src/main/resources/i18n/ApiError_de.properties @@ -1,72 +1,14 @@ -UNKNOWN=Unbekannter Fehler -JSON=JSON Nachricht konnte nicht geparsed werden -NO_BALANCE=Guthaben ungenügend -NOT_YET_RELEASED=Feature wurde noch nicht veröffentlicht -INVALID_SIGNATURE=Ungültige Signatur -INVALID_ADDRESS=Ungültige Adresse -INVALID_SEED=Ungültiger Seed -INVALID_AMOUNT=Ungültiger Betrag -INVALID_FEE=Ungültige Gebühr -INVALID_SENDER=Ungültiger Sender -INVALID_RECIPIENT=Ungültiger Empfänger -INVALID_NAME_LENGTH=Ungültige Namenslänge -INVALID_VALUE_LENGTH=Ungültige Wertlänge -INVALID_NAME_OWNER=Ungültiger Namensbesitzer -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! + +INVALID_ADDRESS = ung\u00FCltige adresse + +INVALID_ASSET_ID = ung\u00FCltige asset ID + +INVALID_DATA = ung\u00FCltige daten + +INVALID_PUBLIC_KEY = ung\u00FCltiger public key + +INVALID_SIGNATURE = ung\u00FCltige signatur + +JSON = JSON nachricht konnte nicht geparsed werden + +PUBLIC_KEY_NOT_FOUND = public key wurde nicht gefunden diff --git a/src/main/resources/i18n/ApiError_en.properties b/src/main/resources/i18n/ApiError_en.properties index 7b5bd8c4..52d99740 100644 --- a/src/main/resources/i18n/ApiError_en.properties +++ b/src/main/resources/i18n/ApiError_en.properties @@ -1,100 +1,57 @@ +#Generated by ResourceBundle Editor (http://essiembre.github.io/eclipse-rbe/) # 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 +ADDRESS_UNKNOWN = account address unknown -# 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 +BLOCKCHAIN_NEEDS_SYNC = blockchain needs to synchronize first # Blocks -BLOCK_NO_EXISTS=block does not exist +BLOCK_UNKNOWN = block unknown -# Transactions -TRANSACTION_NO_EXISTS=transaction does not exist -PUBLIC_KEY_NOT_FOUND=public key not found -TRANSACTION_INVALID=transaction invalid: %s +CANNOT_MINT = account cannot mint -# 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 +GROUP_UNKNOWN = group unknown -# 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 +INVALID_ADDRESS = invalid address # Assets -INVALID_ASSET_ID=invalid asset id -INVALID_ORDER_ID=invalid asset order id -ORDER_NO_EXISTS=unknown asset order id +INVALID_ASSET_ID = invalid asset 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 +INVALID_CRITERIA = invalid search criteria -# 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 +INVALID_DATA = invalid data -# 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! +INVALID_HEIGHT = invalid block height + +INVALID_NETWORK_ADDRESS = invalid network address + +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 diff --git a/src/main/resources/i18n/ApiError_zh.properties b/src/main/resources/i18n/ApiError_zh.properties deleted file mode 100644 index 7b5bd8c4..00000000 --- a/src/main/resources/i18n/ApiError_zh.properties +++ /dev/null @@ -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! diff --git a/src/main/resources/i18n/TransactionValidity_en.properties b/src/main/resources/i18n/TransactionValidity_en.properties index 8f16b499..e162b7c0 100644 --- a/src/main/resources/i18n/TransactionValidity_en.properties +++ b/src/main/resources/i18n/TransactionValidity_en.properties @@ -1,42 +1,174 @@ -OK=OK -INVALID_ADDRESS=INVALID_ADDRESS -NEGATIVE_AMOUNT=NEGATIVE_AMOUNT -NEGATIVE_FEE=NEGATIVE_FEE -NO_BALANCE=NO_BALANCE -INVALID_REFERENCE=INVALID_REFERENCE -INVALID_NAME_LENGTH=INVALID_NAME_LENGTH -INVALID_VALUE_LENGTH=INVALID_VALUE_LENGTH -NAME_ALREADY_REGISTERED=NAME_ALREADY_REGISTERED -NAME_DOES_NOT_EXIST=NAME_DOES_NOT_EXIST -INVALID_NAME_OWNER=INVALID_NAME_OWNER -NAME_ALREADY_FOR_SALE=NAME_ALREADY_FOR_SALE -NAME_NOT_FOR_SALE=NAME_NOT_FOR_SALE -BUYER_ALREADY_OWNER=BUYER_ALREADY_OWNER -INVALID_AMOUNT=INVALID_AMOUNT -INVALID_SELLER=INVALID_SELLER -NAME_NOT_LOWER_CASE=NAME_NOT_LOWER_CASE -INVALID_DESCRIPTION_LENGTH=INVALID_DESCRIPTION_LENGTH -INVALID_OPTIONS_COUNT=INVALID_OPTIONS_COUNT -INVALID_OPTION_LENGTH=INVALID_OPTION_LENGTH -DUPLICATE_OPTION=DUPLICATE_OPTION -POLL_ALREADY_EXISTS=POLL_ALREADY_EXISTS -POLL_DOES_NOT_EXIST=POLL_DOES_NOT_EXIST -POLL_OPTION_DOES_NOT_EXIST=POLL_OPTION_DOES_NOT_EXIST -ALREADY_VOTED_FOR_THAT_OPTION=ALREADY_VOTED_FOR_THAT_OPTION -INVALID_DATA_LENGTH=INVALID_DATA_LENGTH -INVALID_QUANTITY=INVALID_QUANTITY -ASSET_DOES_NOT_EXIST=ASSET_DOES_NOT_EXIST -INVALID_RETURN=INVALID_RETURN -HAVE_EQUALS_WANT=HAVE_EQUALS_WANT -ORDER_DOES_NOT_EXIST=ORDER_DOES_NOT_EXIST -INVALID_ORDER_CREATOR=INVALID_ORDER_CREATOR -INVALID_PAYMENTS_COUNT=INVALID_PAYMENTS_COUNT -NEGATIVE_PRICE=NEGATIVE_PRICE -INVALID_CREATION_BYTES=INVALID_CREATION_BYTES -INVALID_TAGS_LENGTH=INVALID_TAGS_LENGTH -INVALID_AT_TYPE_LENGTH=INVALID_AT_TYPE_LENGTH -INVALID_AT_TRANSACTION=INVALID_AT_TRANSACTION -AT_IS_FINISHED=AT_IS_FINISHED -ASSET_DOES_NOT_MATCH_AT=ASSET_DOES_NOT_MATCH_AT -ASSET_ALREADY_EXISTS=ASSET_ALREADY_EXISTS -NOT_YET_RELEASED=NOT_YET_RELEASED + +ACCOUNT_CANNOT_REWARD_SHARE = account cannot reward-share + +ALREADY_GROUP_ADMIN = already group admin + +ALREADY_GROUP_MEMBER = already group member + +ALREADY_VOTED_FOR_THAT_OPTION = already voted for that option + +ASSET_ALREADY_EXISTS = asset already exists + +ASSET_DOES_NOT_EXIST = ASSET_DOES_NOT_EXIST + +ASSET_DOES_NOT_MATCH_AT = ASSET_DOES_NOT_MATCH_AT + +ASSET_NOT_SPENDABLE = ASSET_NOT_SPENDABLE + +AT_ALREADY_EXISTS = AT_ALREADY_EXISTS + +AT_IS_FINISHED = AT_IS_FINISHED + +AT_UNKNOWN = AT_UNKNOWN + +BANNED_FROM_GROUP = BANNED_FROM_GROUP + +BAN_EXISTS = BAN_EXISTS + +BAN_UNKNOWN = BAN_UNKNOWN + +BUYER_ALREADY_OWNER = BUYER_ALREADY_OWNER + +CLOCK_NOT_SYNCED = CLOCK_NOT_SYNCED + +DUPLICATE_OPTION = DUPLICATE_OPTION + +GROUP_ALREADY_EXISTS = GROUP_ALREADY_EXISTS + +GROUP_APPROVAL_DECIDED = GROUP_APPROVAL_DECIDED + +GROUP_APPROVAL_NOT_REQUIRED = GROUP_APPROVAL_NOT_REQUIRED + +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 diff --git a/src/test/java/org/qortal/test/api/AssetsApiTests.java b/src/test/java/org/qortal/test/api/AssetsApiTests.java index 993123b9..cf49ec6a 100644 --- a/src/test/java/org/qortal/test/api/AssetsApiTests.java +++ b/src/test/java/org/qortal/test/api/AssetsApiTests.java @@ -94,7 +94,7 @@ public class AssetsApiTests extends ApiCommon { try { assertNotNull(this.assetsResource.getAssetOrder(FAKE_ORDER_ID_BASE58)); } 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 { assertNotNull(this.assetsResource.getAssetOrderTrades(FAKE_ORDER_ID_BASE58, null, null, null)); } catch (ApiException e) { - assertTrue(e.error == ApiError.ORDER_NO_EXISTS.getCode()); + assertTrue(e.error == ApiError.ORDER_UNKNOWN.getCode()); } try { assertNotNull(this.assetsResource.getAssetOrderTrades(FAKE_ORDER_ID_BASE58, 1, 1, true)); } catch (ApiException e) { - assertTrue(e.error == ApiError.ORDER_NO_EXISTS.getCode()); + assertTrue(e.error == ApiError.ORDER_UNKNOWN.getCode()); } } diff --git a/src/test/java/org/qortal/test/apps/CheckTranslations.java b/src/test/java/org/qortal/test/apps/CheckTranslations.java new file mode 100644 index 00000000..df15b67e --- /dev/null +++ b/src/test/java/org/qortal/test/apps/CheckTranslations.java @@ -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 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 keys) { + System.out.println(String.format("## Checking '%s' translations for %s", lang, className)); + + Set 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)); + } + +}