forked from Qortal/qortal
CHANGED: translation support for API resources
This commit is contained in:
parent
2eb808a0b7
commit
9a3eb186cc
104
globalization/Api.de.xml
Normal file
104
globalization/Api.de.xml
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<localization>
|
||||||
|
<context locale="de">
|
||||||
|
<context path="Api">
|
||||||
|
<context path="ApiError">
|
||||||
|
<translation key="0" template="Unbekannter Fehler" />
|
||||||
|
<translation key="1" template="JSON Nachricht konnte nicht geparsed werden" />
|
||||||
|
<translation key="2" template="Guthaben ungenügend" />
|
||||||
|
<translation key="3" template="Feature wurde noch nicht veröffentlicht" />
|
||||||
|
|
||||||
|
<translation key="101" template="Ungültige Signatur" />
|
||||||
|
<translation key="102" template="Ungültige Adresse" />
|
||||||
|
<translation key="103" template="Ungültiger Seed" />
|
||||||
|
<translation key="104" template="Ungültiger Betrag" />
|
||||||
|
<translation key="105" template="Ungültige Gebühr" />
|
||||||
|
<translation key="106" template="Ungültiger Sender" />
|
||||||
|
<translation key="107" template="Ungültiger Empfänger" />
|
||||||
|
<translation key="108" template="Ungültige Namenslänge" />
|
||||||
|
<translation key="109" template="Ungültige Wertlänge" />
|
||||||
|
<translation key="110" template="Ungültiger Namensbesitzer" />
|
||||||
|
<translation key="111" template="Ungültiger Käufer" />
|
||||||
|
<translation key="112" template="Ungültiger Public Key" />
|
||||||
|
<translation key="113" template="Ungültige Optionen-Länge" />
|
||||||
|
<translation key="114" template="Ungültige Optionslänge" />
|
||||||
|
<translation key="115" template="Ungültige Daten" />
|
||||||
|
<translation key="116" template="Ungültige Datenlänge" />
|
||||||
|
<translation key="117" template="Ungültiger Update-Wert" />
|
||||||
|
<translation key="118" template="Der Schlüssel existiert bereits, Editieren ist deaktiviert" />
|
||||||
|
<translation key="119" template="Der Schlüssel existiert nicht" />
|
||||||
|
<translation key="120" template="Du kannst den Schlüssel '${key}' nicht löschen, wenn er der einzige ist" />
|
||||||
|
<translation key="121" template="fee less required" />
|
||||||
|
<translation key="122" template="Das Wallet muss synchronisiert werden" />
|
||||||
|
<translation key="123" template="Ungültige Netzwerkadresse" />
|
||||||
|
|
||||||
|
<translation key="201" template="Das Wallet existiert nicht" />
|
||||||
|
<translation key="202" template="Die Adresse existiert nicht im Wallet" />
|
||||||
|
<translation key="203" template="Das Wallet ist abgeschlossen" />
|
||||||
|
<translation key="204" template="Das Wallet existiert bereits" />
|
||||||
|
<translation key="205" template="Der Benutzer hat den API-Aufruf abgelehnt" />
|
||||||
|
|
||||||
|
<translation key="301" template="Der Block existiert nicht" />
|
||||||
|
<translation key="311" template="Die Transaktion existiert nicht" />
|
||||||
|
<translation key="304" template="Public Key wurde nicht gefunden" />
|
||||||
|
|
||||||
|
<translation key="401" template="Der Name existiert nicht" />
|
||||||
|
<translation key="402" template="Der Name existiert bereits" />
|
||||||
|
<translation key="403" template="Der Name steht bereits zum Verkauf" />
|
||||||
|
<translation key="404" template="Der Name muss aus Kleinbuchstaben bestehen" />
|
||||||
|
<translation key="410" template="Namensverkauf existiert nicht" />
|
||||||
|
<translation key="411" template="Der Käufer ist bereits Besitzer" />
|
||||||
|
|
||||||
|
<translation key="501" template="Die Abstimmung existiert nicht" />
|
||||||
|
<translation key="502" template="Die Abstimmung existiert bereits" />
|
||||||
|
<translation key="503" template="Nicht alle Optionen sind eindeutig" />
|
||||||
|
<translation key="504" template="Die option existiert nicht" />
|
||||||
|
<translation key="505" template="Bereits für diese Option abgestimmt" />
|
||||||
|
|
||||||
|
<translation key="601" template="Ungültige Asset ID" />
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<translation key="701" template="?NAME_NOT_REGISTERED?" />
|
||||||
|
<translation key="702" template="?NAME_FOR_SALE?" />
|
||||||
|
<translation key="703" template="?NAME_WITH_SPACE?" />
|
||||||
|
-->
|
||||||
|
|
||||||
|
<translation key="801" template="Ungültige Beschreibungslänge. Max. Länge ${MAX_LENGTH}" />
|
||||||
|
<translation key="802" template="Der Code ist leer" />
|
||||||
|
<translation key="803" template="Ungültige Datenlänge" />
|
||||||
|
<translation key="804" template="Ungültige Seiten" />
|
||||||
|
<translation key="805" template="Ungültige Typlänge" />
|
||||||
|
<translation key="806" template="Ungültige Tag-Länge" />
|
||||||
|
<translation key="809" template="Fehler in Creation Bytes" />
|
||||||
|
|
||||||
|
<translation key="901" template="invalid body it must not be empty" />
|
||||||
|
<translation key="902" template="Dieser Blog ist deaktiviert" />
|
||||||
|
<translation key="903" template="the creator address does not own the author name" />
|
||||||
|
<translation key="904" template="the data size is too large - currently only ${BATCH_TX_AMOUNT} arbitrary transactions are allowed at once!" />
|
||||||
|
<translation key="905" template="transaction with this signature contains no entries!" />
|
||||||
|
<translation key="906" template="this blog is empty" />
|
||||||
|
<translation key="907" template="the attribute postid is empty! this is the signature of the post you want to comment" />
|
||||||
|
<translation key="908" template="for the given postid no blogpost to comment was found" />
|
||||||
|
<translation key="909" template="commenting is for this blog disabled" />
|
||||||
|
<translation key="910" template="for the given signature no comment was found" />
|
||||||
|
<translation key="911" template="invalid comment owner" />
|
||||||
|
|
||||||
|
<translation key="1001" template="the Message format is not hex - correct the text or use isTextMessage = true" />
|
||||||
|
<translation key="1002" template="The message attribute is missing or content is blank" />
|
||||||
|
<translation key="1003" template="The recipient has not yet performed any action in the blockchain.\nYou can't send an encrypted message to him." />
|
||||||
|
<translation key="1004" template="Message size exceeded!" />
|
||||||
|
</context>
|
||||||
|
|
||||||
|
<context path="ApiClient">
|
||||||
|
<translation key="invalid command" template="Ungültiger Befehl!\nGib 'help all' ein, um eine Liste aller gültigen Befehle zu erhalten." />
|
||||||
|
<translation key="error footer" template="Gib 'help all' ein, um eine Liste aller gültigen Befehle zu erhalten." />
|
||||||
|
|
||||||
|
<translation key="help: success responses" template="Antwort bei Erfolg:" />
|
||||||
|
<translation key="help: failure responses" template="Antwort bei Misserfolg:" />
|
||||||
|
</context>
|
||||||
|
|
||||||
|
</context>
|
||||||
|
|
||||||
|
</context>
|
||||||
|
|
||||||
|
</localization>
|
108
globalization/Api.en.xml
Normal file
108
globalization/Api.en.xml
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<localization>
|
||||||
|
<context locale="en">
|
||||||
|
<context path="Api">
|
||||||
|
<context path="ApiError">
|
||||||
|
<translation key="0" template="unknown error" />
|
||||||
|
<translation key="1" template="failed to parse json message" />
|
||||||
|
<translation key="2" template="not enough balance" />
|
||||||
|
<translation key="3" template="that feature is not yet released" />
|
||||||
|
|
||||||
|
<translation key="101" template="invalid signature" />
|
||||||
|
<translation key="102" template="invalid address" />
|
||||||
|
<translation key="103" template="invalid seed" />
|
||||||
|
<translation key="104" template="invalid amount" />
|
||||||
|
<translation key="105" template="invalid fee" />
|
||||||
|
<translation key="106" template="invalid sender" />
|
||||||
|
<translation key="107" template="invalid recipient" />
|
||||||
|
<translation key="108" template="invalid name length" />
|
||||||
|
<translation key="109" template="invalid value length" />
|
||||||
|
<translation key="110" template="invalid name owner" />
|
||||||
|
<translation key="111" template="invalid buyer" />
|
||||||
|
<translation key="112" template="invalid public key" />
|
||||||
|
<translation key="113" template="invalid options length" />
|
||||||
|
<translation key="114" template="invalid option length" />
|
||||||
|
<translation key="115" template="invalid data" />
|
||||||
|
<translation key="116" template="invalid data length" />
|
||||||
|
<translation key="117" template="invalid update value" />
|
||||||
|
<translation key="118" template="key already exists, edit is false" />
|
||||||
|
<translation key="119" template="the key does not exist" />
|
||||||
|
<translation key="120" template="you can't delete the key '${key}' if it is the only key" />
|
||||||
|
<translation key="121" template="fee less required" />
|
||||||
|
<translation key="122" template="wallet needs to be synchronized" />
|
||||||
|
<translation key="123" template="invalid network address" />
|
||||||
|
|
||||||
|
<translation key="201" template="wallet does not exist" />
|
||||||
|
<translation key="202" template="address does not exist in wallet" />
|
||||||
|
<translation key="203" template="wallet is locked" />
|
||||||
|
<translation key="204" template="wallet already exists" />
|
||||||
|
<translation key="205" template="user denied api call" />
|
||||||
|
|
||||||
|
<translation key="301" template="block does not exist" />
|
||||||
|
<translation key="311" template="transactions does not exist" />
|
||||||
|
<translation key="304" template="public key not found" />
|
||||||
|
|
||||||
|
<translation key="401" template="name does not exist" />
|
||||||
|
<translation key="402" template="name already exists" />
|
||||||
|
<translation key="403" template="name already for sale" />
|
||||||
|
<translation key="404" template="name must be lower case" />
|
||||||
|
<translation key="410" template="namesale does not exist" />
|
||||||
|
<translation key="411" template="buyer is already owner" />
|
||||||
|
|
||||||
|
<translation key="501" template="poll does not exist" />
|
||||||
|
<translation key="502" template="poll already exists" />
|
||||||
|
<translation key="503" template="not all options are unique" />
|
||||||
|
<translation key="504" template="option does not exist" />
|
||||||
|
<translation key="505" template="already voted for that option" />
|
||||||
|
|
||||||
|
<translation key="601" template="invalid asset id" />
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<translation key="701" template="?NAME_NOT_REGISTERED?" />
|
||||||
|
<translation key="702" template="?NAME_FOR_SALE?" />
|
||||||
|
<translation key="703" template="?NAME_WITH_SPACE?" />
|
||||||
|
-->
|
||||||
|
|
||||||
|
<translation key="801" template="invalid description length. max length ${MAX_LENGTH}" />
|
||||||
|
<translation key="802" template="code is empty" />
|
||||||
|
<translation key="803" template="invalid data length" />
|
||||||
|
<translation key="804" template="invalid pages" />
|
||||||
|
<translation key="805" template="invalid type length" />
|
||||||
|
<translation key="806" template="invalid tags length" />
|
||||||
|
<translation key="809" template="error in creation bytes" />
|
||||||
|
|
||||||
|
<translation key="901" template="invalid body it must not be empty" />
|
||||||
|
<translation key="902" template="this blog is disabled" />
|
||||||
|
<translation key="903" template="the creator address does not own the author name" />
|
||||||
|
<translation key="904" template="the data size is too large - currently only ${BATCH_TX_AMOUNT} arbitrary transactions are allowed at once!" />
|
||||||
|
<translation key="905" template="transaction with this signature contains no entries!" />
|
||||||
|
<translation key="906" template="this blog is empty" />
|
||||||
|
<translation key="907" template="the attribute postid is empty! this is the signature of the post you want to comment" />
|
||||||
|
<translation key="908" template="for the given postid no blogpost to comment was found" />
|
||||||
|
<translation key="909" template="commenting is for this blog disabled" />
|
||||||
|
<translation key="910" template="for the given signature no comment was found" />
|
||||||
|
<translation key="911" template="invalid comment owner" />
|
||||||
|
|
||||||
|
<translation key="1001" template="the Message format is not hex - correct the text or use isTextMessage = true" />
|
||||||
|
<translation key="1002" template="The message attribute is missing or content is blank" />
|
||||||
|
<translation key="1003" template="The recipient has not yet performed any action in the blockchain.\nYou can't send an encrypted message to him." />
|
||||||
|
<translation key="1004" template="Message size exceeded!" />
|
||||||
|
</context>
|
||||||
|
|
||||||
|
<context path="ApiClient">
|
||||||
|
<translation key="invalid command" template="Invalid command! \nType 'help all' to get a list of commands." />
|
||||||
|
<translation key="error footer" template="Type 'help all' to get a list of commands." />
|
||||||
|
|
||||||
|
<translation key="API error response" template="(API error: ${ERROR_CODE}) ${DESCRIPTION}" />
|
||||||
|
|
||||||
|
<translation key="error: with body" template="HTTP Status ${STATUS}: ${BODY}" />
|
||||||
|
<translation key="error: without body" template="HTTP Status ${STATUS}" />
|
||||||
|
<translation key="help: success responses" template="On success returns:" />
|
||||||
|
<translation key="help: failure responses" template="On failure returns:" />
|
||||||
|
</context>
|
||||||
|
|
||||||
|
</context>
|
||||||
|
|
||||||
|
</context>
|
||||||
|
|
||||||
|
</localization>
|
60
globalization/BlocksResource.de.xml
Normal file
60
globalization/BlocksResource.de.xml
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<localization>
|
||||||
|
<context locale="de">
|
||||||
|
|
||||||
|
<context path="Api">
|
||||||
|
<context path="BlocksResource">
|
||||||
|
<context path="GET">
|
||||||
|
<translation key="operation:description" template="Gibt ein Array der letzten 50 Blöcke zurück, die von deinem Account erzeugt wurden" />
|
||||||
|
<translation key="success_response:description" template="Die Blöcke" />
|
||||||
|
</context>
|
||||||
|
<!--<context path="GET address:address">
|
||||||
|
<translation key="operation:description" template="returns an array of the 50 last blocks generated by a specific address in your wallet" />
|
||||||
|
<translation key="success_response:description" template="the blocks" />
|
||||||
|
</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>
|
60
globalization/BlocksResource.en.xml
Normal file
60
globalization/BlocksResource.en.xml
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<localization>
|
||||||
|
<context locale="en">
|
||||||
|
|
||||||
|
<context path="Api">
|
||||||
|
<context path="BlocksResource">
|
||||||
|
<context path="GET">
|
||||||
|
<translation key="operation:description" template="returns an array of the 50 last blocks generated by your accounts" />
|
||||||
|
<translation key="success_response:description" template="the blocks" />
|
||||||
|
</context>
|
||||||
|
<context path="GET address:address">
|
||||||
|
<translation key="operation:description" template="returns an array of the 50 last blocks generated by a specific address in your wallet" />
|
||||||
|
<translation key="success_response:description" template="the blocks" />
|
||||||
|
</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>
|
@ -1,23 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<localization>
|
|
||||||
<context locale="en">
|
|
||||||
<context path="Api">
|
|
||||||
<context path="ApiError">
|
|
||||||
<translation key="0" template="unknown error" />
|
|
||||||
<translation key="1" template="failed to parse json message" />
|
|
||||||
<translation key="2" template="not enough balance" />
|
|
||||||
<translation key="3" template="that feature is not yet released" />
|
|
||||||
|
|
||||||
<translation key="201" template="wallet does not exist" />
|
|
||||||
</context>
|
|
||||||
|
|
||||||
<context path="BlocksResource">
|
|
||||||
<context path="GET byheight">
|
|
||||||
<translation key="success.description" template="Test" />
|
|
||||||
</context>
|
|
||||||
</context>
|
|
||||||
</context>
|
|
||||||
|
|
||||||
</context>
|
|
||||||
|
|
||||||
</localization>
|
|
@ -8,82 +8,19 @@ import io.swagger.v3.jaxrs2.ReaderListener;
|
|||||||
import io.swagger.v3.oas.models.OpenAPI;
|
import io.swagger.v3.oas.models.OpenAPI;
|
||||||
import io.swagger.v3.oas.models.Operation;
|
import io.swagger.v3.oas.models.Operation;
|
||||||
import io.swagger.v3.oas.models.PathItem;
|
import io.swagger.v3.oas.models.PathItem;
|
||||||
import io.swagger.v3.oas.models.Paths;
|
|
||||||
import io.swagger.v3.oas.models.info.Info;
|
import io.swagger.v3.oas.models.info.Info;
|
||||||
import io.swagger.v3.oas.models.responses.ApiResponse;
|
import io.swagger.v3.oas.models.responses.ApiResponse;
|
||||||
import static java.util.Arrays.asList;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class AnnotationPostProcessor implements ReaderListener {
|
public class AnnotationPostProcessor implements ReaderListener {
|
||||||
|
|
||||||
private interface TranslatableProperty<T> {
|
|
||||||
public String keyName();
|
|
||||||
public void setValue(T item, String translation);
|
|
||||||
public String getValue(T item);
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ContextInformation {
|
private class ContextInformation {
|
||||||
public String path;
|
public String path;
|
||||||
public Map<String, String> keys;
|
public Map<String, String> keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String TRANSLATION_EXTENTION_NAME = "x-translation";
|
|
||||||
|
|
||||||
private static final List<TranslatableProperty<Info>> translatableInfoProperties = asList(
|
|
||||||
new TranslatableProperty<Info>() {
|
|
||||||
@Override public String keyName() { return "description.key"; }
|
|
||||||
@Override public void setValue(Info item, String translation) { item.setDescription(translation); }
|
|
||||||
@Override public String getValue(Info item) { return item.getDescription(); }
|
|
||||||
},
|
|
||||||
new TranslatableProperty<Info>() {
|
|
||||||
@Override public String keyName() { return "title.key"; }
|
|
||||||
@Override public void setValue(Info item, String translation) { item.setTitle(translation); }
|
|
||||||
@Override public String getValue(Info item) { return item.getTitle(); }
|
|
||||||
},
|
|
||||||
new TranslatableProperty<Info>() {
|
|
||||||
@Override public String keyName() { return "termsOfService.key"; }
|
|
||||||
@Override public void setValue(Info item, String translation) { item.setTermsOfService(translation); }
|
|
||||||
@Override public String getValue(Info item) { return item.getTermsOfService(); }
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
private static final List<TranslatableProperty<PathItem>> translatablePathItemProperties = asList(
|
|
||||||
new TranslatableProperty<PathItem>() {
|
|
||||||
@Override public String keyName() { return "description.key"; }
|
|
||||||
@Override public void setValue(PathItem item, String translation) { item.setDescription(translation); }
|
|
||||||
@Override public String getValue(PathItem item) { return item.getDescription(); }
|
|
||||||
},
|
|
||||||
new TranslatableProperty<PathItem>() {
|
|
||||||
@Override public String keyName() { return "summary.key"; }
|
|
||||||
@Override public void setValue(PathItem item, String translation) { item.setSummary(translation); }
|
|
||||||
@Override public String getValue(PathItem item) { return item.getSummary(); }
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
private static final List<TranslatableProperty<Operation>> translatableOperationProperties = asList(
|
|
||||||
new TranslatableProperty<Operation>() {
|
|
||||||
@Override public String keyName() { return "description.key"; }
|
|
||||||
@Override public void setValue(Operation item, String translation) { item.setDescription(translation); }
|
|
||||||
@Override public String getValue(Operation item) { return item.getDescription(); }
|
|
||||||
},
|
|
||||||
new TranslatableProperty<Operation>() {
|
|
||||||
@Override public String keyName() { return "summary.key"; }
|
|
||||||
@Override public void setValue(Operation item, String translation) { item.setSummary(translation); }
|
|
||||||
@Override public String getValue(Operation item) { return item.getSummary(); }
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
private static final List<TranslatableProperty<ApiResponse>> translatableApiResponseProperties = asList(
|
|
||||||
new TranslatableProperty<ApiResponse>() {
|
|
||||||
@Override public String keyName() { return "description.key"; }
|
|
||||||
@Override public void setValue(ApiResponse item, String translation) { item.setDescription(translation); }
|
|
||||||
@Override public String getValue(ApiResponse item) { return item.getDescription(); }
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
private final Translator translator;
|
private final Translator translator;
|
||||||
|
|
||||||
public AnnotationPostProcessor() {
|
public AnnotationPostProcessor() {
|
||||||
@ -92,8 +29,6 @@ public class AnnotationPostProcessor implements ReaderListener {
|
|||||||
|
|
||||||
public AnnotationPostProcessor(Translator translator) {
|
public AnnotationPostProcessor(Translator translator) {
|
||||||
this.translator = translator;
|
this.translator = translator;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -106,25 +41,25 @@ public class AnnotationPostProcessor implements ReaderListener {
|
|||||||
Info resourceInfo = openAPI.getInfo();
|
Info resourceInfo = openAPI.getInfo();
|
||||||
ContextInformation resourceContext = getContextInformation(openAPI.getExtensions());
|
ContextInformation resourceContext = getContextInformation(openAPI.getExtensions());
|
||||||
removeTranslationAnnotations(openAPI.getExtensions());
|
removeTranslationAnnotations(openAPI.getExtensions());
|
||||||
TranslateProperty(translatableInfoProperties, resourceContext, resourceInfo);
|
TranslateProperty(Constants.TRANSLATABLE_INFO_PROPERTIES, resourceContext, resourceInfo);
|
||||||
|
|
||||||
for (Map.Entry<String, PathItem> pathEntry : openAPI.getPaths().entrySet())
|
for (Map.Entry<String, PathItem> pathEntry : openAPI.getPaths().entrySet())
|
||||||
{
|
{
|
||||||
PathItem pathItem = pathEntry.getValue();
|
PathItem pathItem = pathEntry.getValue();
|
||||||
ContextInformation pathContext = getContextInformation(pathItem.getExtensions(), resourceContext);
|
ContextInformation pathContext = getContextInformation(pathItem.getExtensions(), resourceContext);
|
||||||
removeTranslationAnnotations(pathItem.getExtensions());
|
removeTranslationAnnotations(pathItem.getExtensions());
|
||||||
TranslateProperty(translatablePathItemProperties, pathContext, pathItem);
|
TranslateProperty(Constants.TRANSLATABLE_PATH_ITEM_PROPERTIES, pathContext, pathItem);
|
||||||
|
|
||||||
for (Operation operation : pathItem.readOperations()) {
|
for (Operation operation : pathItem.readOperations()) {
|
||||||
ContextInformation operationContext = getContextInformation(operation.getExtensions(), pathContext);
|
ContextInformation operationContext = getContextInformation(operation.getExtensions(), pathContext);
|
||||||
removeTranslationAnnotations(operation.getExtensions());
|
removeTranslationAnnotations(operation.getExtensions());
|
||||||
TranslateProperty(translatableOperationProperties, operationContext, operation);
|
TranslateProperty(Constants.TRANSLATABLE_OPERATION_PROPERTIES, operationContext, operation);
|
||||||
|
|
||||||
for (Map.Entry<String, ApiResponse> responseEntry : operation.getResponses().entrySet()) {
|
for (Map.Entry<String, ApiResponse> responseEntry : operation.getResponses().entrySet()) {
|
||||||
ApiResponse response = responseEntry.getValue();
|
ApiResponse response = responseEntry.getValue();
|
||||||
ContextInformation responseContext = getContextInformation(response.getExtensions(), operationContext);
|
ContextInformation responseContext = getContextInformation(response.getExtensions(), operationContext);
|
||||||
removeTranslationAnnotations(response.getExtensions());
|
removeTranslationAnnotations(response.getExtensions());
|
||||||
TranslateProperty(translatableApiResponseProperties, responseContext, response);
|
TranslateProperty(Constants.TRANSLATABLE_API_RESPONSE_PROPERTIES, responseContext, response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -137,8 +72,8 @@ public class AnnotationPostProcessor implements ReaderListener {
|
|||||||
String key = keys.get(prop.keyName());
|
String key = keys.get(prop.keyName());
|
||||||
if(key != null) {
|
if(key != null) {
|
||||||
String originalValue = prop.getValue(item);
|
String originalValue = prop.getValue(item);
|
||||||
// XXX: use configurable or browser locale instead english?
|
// XXX: use browser locale instead default?
|
||||||
String translation = translator.translate(Locale.ENGLISH, context.path, key, originalValue);
|
String translation = translator.translate(context.path, key, originalValue);
|
||||||
prop.setValue(item, translation);
|
prop.setValue(item, translation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -151,10 +86,10 @@ public class AnnotationPostProcessor implements ReaderListener {
|
|||||||
|
|
||||||
private ContextInformation getContextInformation(Map<String, Object> extensions, ContextInformation base) {
|
private ContextInformation getContextInformation(Map<String, Object> extensions, ContextInformation base) {
|
||||||
if(extensions != null) {
|
if(extensions != null) {
|
||||||
Map<String, Object> translationDefinitions = (Map<String, Object>)extensions.get(TRANSLATION_EXTENTION_NAME);
|
Map<String, Object> translationDefinitions = (Map<String, Object>)extensions.get("x-" + Constants.TRANSLATION_EXTENSION_NAME);
|
||||||
if(translationDefinitions != null) {
|
if(translationDefinitions != null) {
|
||||||
ContextInformation result = new ContextInformation();
|
ContextInformation result = new ContextInformation();
|
||||||
result.path = getAbsolutePath(base, (String)translationDefinitions.get("path"));
|
result.path = combinePaths(base, (String)translationDefinitions.get(Constants.TRANSLATION_PATH_EXTENSION_NAME));
|
||||||
result.keys = getTranslationKeys(translationDefinitions);
|
result.keys = getTranslationKeys(translationDefinitions);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -173,13 +108,13 @@ public class AnnotationPostProcessor implements ReaderListener {
|
|||||||
if(extensions == null)
|
if(extensions == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
extensions.remove(TRANSLATION_EXTENTION_NAME);
|
extensions.remove("x-" + Constants.TRANSLATION_EXTENSION_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, String> getTranslationKeys(Map<String, Object> translationDefinitions) {
|
private Map<String, String> getTranslationKeys(Map<String, Object> translationDefinitions) {
|
||||||
Map<String, String> result = new HashMap<>();
|
Map<String, String> result = new HashMap<>();
|
||||||
|
|
||||||
for(TranslatableProperty prop : translatableInfoProperties) {
|
for(TranslatableProperty prop : Constants.TRANSLATABLE_INFO_PROPERTIES) {
|
||||||
String key = (String)translationDefinitions.get(prop.keyName());
|
String key = (String)translationDefinitions.get(prop.keyName());
|
||||||
if(key != null)
|
if(key != null)
|
||||||
result.put(prop.keyName(), key);
|
result.put(prop.keyName(), key);
|
||||||
@ -188,10 +123,8 @@ public class AnnotationPostProcessor implements ReaderListener {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getAbsolutePath(ContextInformation base, String path) {
|
private String combinePaths(ContextInformation base, String path) {
|
||||||
String result = (base != null) ? base.path : "/";
|
String basePath = (base != null) ? base.path : null;
|
||||||
path = (path != null) ? path : "";
|
return ContextPaths.combinePaths(basePath, path);
|
||||||
result = ContextPaths.combinePaths(result, path);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,20 @@
|
|||||||
package api;
|
package api;
|
||||||
|
|
||||||
|
import globalization.ContextPaths;
|
||||||
import globalization.Translator;
|
import globalization.Translator;
|
||||||
import io.swagger.v3.jaxrs2.integration.resources.OpenApiResource;
|
import io.swagger.v3.jaxrs2.integration.resources.OpenApiResource;
|
||||||
|
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.extensions.Extension;
|
||||||
|
import io.swagger.v3.oas.annotations.extensions.ExtensionProperty;
|
||||||
import io.swagger.v3.oas.annotations.media.Content;
|
import io.swagger.v3.oas.annotations.media.Content;
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.AbstractMap;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
@ -49,6 +53,8 @@ public class ApiClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final String TRANSLATION_CONTEXT_PATH = "/Api/ApiClient";
|
||||||
|
|
||||||
private static final Pattern COMMAND_PATTERN = Pattern.compile("^ *(?<method>GET|POST|PUT|PATCH|DELETE) *(?<path>.*)$");
|
private static final Pattern COMMAND_PATTERN = Pattern.compile("^ *(?<method>GET|POST|PUT|PATCH|DELETE) *(?<path>.*)$");
|
||||||
private static final Pattern HELP_COMMAND_PATTERN = Pattern.compile("^ *help *(?<command>.*)$", Pattern.CASE_INSENSITIVE);
|
private static final Pattern HELP_COMMAND_PATTERN = Pattern.compile("^ *help *(?<command>.*)$", Pattern.CASE_INSENSITIVE);
|
||||||
private static final List<Class<? extends Annotation>> HTTP_METHOD_ANNOTATIONS = Arrays.asList(
|
private static final List<Class<? extends Annotation>> HTTP_METHOD_ANNOTATIONS = Arrays.asList(
|
||||||
@ -59,8 +65,8 @@ public class ApiClient {
|
|||||||
DELETE.class
|
DELETE.class
|
||||||
);
|
);
|
||||||
|
|
||||||
|
private final Translator translator;
|
||||||
ApiService apiService;
|
ApiService apiService;
|
||||||
private Translator translator;
|
|
||||||
List<HelpInfo> helpInfos;
|
List<HelpInfo> helpInfos;
|
||||||
|
|
||||||
public ApiClient(ApiService apiService, Translator translator) {
|
public ApiClient(ApiService apiService, Translator translator) {
|
||||||
@ -94,18 +100,28 @@ public class ApiClient {
|
|||||||
if (resourcePath == null) {
|
if (resourcePath == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
String resourcePathString = resourcePath.value();
|
String resourcePathString = resourcePath.value();
|
||||||
|
|
||||||
|
// get translation context path for resource
|
||||||
|
String resourceContextPath = "/";
|
||||||
|
OpenAPIDefinition openAPIDefinition = resource.getDeclaredAnnotation(OpenAPIDefinition.class);
|
||||||
|
if(openAPIDefinition != null)
|
||||||
|
resourceContextPath = getContextPath(openAPIDefinition.extensions());
|
||||||
|
|
||||||
// scan each method
|
// scan each method
|
||||||
for (Method method : resource.getDeclaredMethods()) {
|
for (Method method : resource.getDeclaredMethods()) {
|
||||||
Operation operationAnnotation = method.getAnnotation(Operation.class);
|
Operation operationAnnotation = method.getAnnotation(Operation.class);
|
||||||
if (operationAnnotation == null) {
|
if (operationAnnotation == null)
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
String description = operationAnnotation.description();
|
String description = operationAnnotation.description();
|
||||||
|
|
||||||
|
// translate
|
||||||
|
String operationContextPath = ContextPaths.combinePaths(resourceContextPath, getContextPath(operationAnnotation.extensions()));
|
||||||
|
String operationDescriptionKey = getDescriptionTranslationKey(operationAnnotation.extensions());
|
||||||
|
if(operationDescriptionKey != null)
|
||||||
|
description = translator.translate(operationContextPath, operationDescriptionKey, description);
|
||||||
|
|
||||||
// extract responses
|
// extract responses
|
||||||
ArrayList success = new ArrayList();
|
ArrayList success = new ArrayList();
|
||||||
ArrayList errors = new ArrayList();
|
ArrayList errors = new ArrayList();
|
||||||
@ -114,6 +130,20 @@ public class ApiClient {
|
|||||||
if(StringUtils.isBlank(responseDescription))
|
if(StringUtils.isBlank(responseDescription))
|
||||||
continue; // ignore responses without description
|
continue; // ignore responses without description
|
||||||
|
|
||||||
|
// translate
|
||||||
|
String responseContextPath = ContextPaths.combinePaths(operationContextPath, getContextPath(response.extensions()));
|
||||||
|
String responseDescriptionKey = getDescriptionTranslationKey(response.extensions());
|
||||||
|
if(responseDescriptionKey != null)
|
||||||
|
responseDescription = translator.translate(responseContextPath, responseDescriptionKey, responseDescription);
|
||||||
|
|
||||||
|
String apiErrorCode = getApiErrorCode(response.extensions());
|
||||||
|
if(apiErrorCode != null) {
|
||||||
|
responseDescription = translator.translate(TRANSLATION_CONTEXT_PATH, "API error response", "(API error: ${ERROR_CODE}) ${DESCRIPTION}",
|
||||||
|
new AbstractMap.SimpleEntry<>("ERROR_CODE", apiErrorCode),
|
||||||
|
new AbstractMap.SimpleEntry<>("DESCRIPTION", responseDescription)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// try to identify response type by status code
|
// try to identify response type by status code
|
||||||
int responseCode = Integer.parseInt(response.responseCode());
|
int responseCode = Integer.parseInt(response.responseCode());
|
||||||
@ -164,6 +194,50 @@ public class ApiClient {
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getApiErrorCode(Extension[] extensions) {
|
||||||
|
if(extensions == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
for(Extension extension : extensions) {
|
||||||
|
if(extension.name() != null && !extension.name().isEmpty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for(ExtensionProperty prop : extension.properties()) {
|
||||||
|
if(Constants.API_ERROR_CODE_EXTENSION_NAME.equals(prop.name())) {
|
||||||
|
return prop.value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getContextPath(Extension[] extensions) {
|
||||||
|
return getTranslationExtensionValue(extensions, Constants.TRANSLATION_PATH_EXTENSION_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getDescriptionTranslationKey(Extension[] extensions) {
|
||||||
|
return getTranslationExtensionValue(extensions, Constants.TRANSLATION_ANNOTATION_DESCRIPTION_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getTranslationExtensionValue(Extension[] extensions, String key) {
|
||||||
|
if(extensions == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
for(Extension extension : extensions) {
|
||||||
|
if(!Constants.TRANSLATION_EXTENSION_NAME.equals(extension.name()))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for(ExtensionProperty prop : extension.properties()) {
|
||||||
|
if(key.equals(prop.name())) {
|
||||||
|
return prop.value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private String getHelpPatternForPath(String path) {
|
private String getHelpPatternForPath(String path) {
|
||||||
path = path
|
path = path
|
||||||
@ -205,7 +279,7 @@ public class ApiClient {
|
|||||||
|
|
||||||
match = COMMAND_PATTERN.matcher(command);
|
match = COMMAND_PATTERN.matcher(command);
|
||||||
if(!match.matches())
|
if(!match.matches())
|
||||||
return this.translator.translate(Locale.getDefault(), "ApiClient: INVALID_COMMAND", "Invalid command! \nType help to get a list of commands.");
|
return this.translator.translate(TRANSLATION_CONTEXT_PATH, "invalid command", "Invalid command! \nType 'help all' to get a list of commands.");
|
||||||
|
|
||||||
// send the command to the API service
|
// send the command to the API service
|
||||||
String method = match.group("method");
|
String method = match.group("method");
|
||||||
@ -225,11 +299,22 @@ public class ApiClient {
|
|||||||
if(status >= 400) {
|
if(status >= 400) {
|
||||||
result.append("HTTP Status ");
|
result.append("HTTP Status ");
|
||||||
result.append(status);
|
result.append(status);
|
||||||
if(!StringUtils.isBlank(body)) {
|
if(StringUtils.isBlank(body)) {
|
||||||
result.append(": ");
|
result.append(
|
||||||
result.append(body);
|
this.translator.translate(TRANSLATION_CONTEXT_PATH, "error without body", "HTTP Status ${STATUS}",
|
||||||
|
new AbstractMap.SimpleEntry<>("STATUS", status)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}else{
|
||||||
|
result.append(
|
||||||
|
this.translator.translate(TRANSLATION_CONTEXT_PATH, "error with body", "HTTP Status ${STATUS}: ${BODY}",
|
||||||
|
new AbstractMap.SimpleEntry<>("STATUS", status),
|
||||||
|
new AbstractMap.SimpleEntry<>("BODY", body)
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
result.append("\nType help to get a list of commands.");
|
result.append("\n");
|
||||||
|
result.append(this.translator.translate(TRANSLATION_CONTEXT_PATH, "error footer", "Type 'help all' to get a list of commands."));
|
||||||
} else {
|
} else {
|
||||||
result.append(body);
|
result.append(body);
|
||||||
}
|
}
|
||||||
@ -240,13 +325,17 @@ public class ApiClient {
|
|||||||
builder.append(help.fullPath + "\n");
|
builder.append(help.fullPath + "\n");
|
||||||
builder.append(" " + help.description + "\n");
|
builder.append(" " + help.description + "\n");
|
||||||
if(help.success != null && help.success.size() > 0) {
|
if(help.success != null && help.success.size() > 0) {
|
||||||
builder.append(" On success returns:\n");
|
builder.append(" ");
|
||||||
|
builder.append(this.translator.translate(TRANSLATION_CONTEXT_PATH, "help: success responses", "On success returns:"));
|
||||||
|
builder.append("\n");
|
||||||
for(String content : help.success) {
|
for(String content : help.success) {
|
||||||
builder.append(" " + content + "\n");
|
builder.append(" " + content + "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(help.errors != null && help.errors.size() > 0) {
|
if(help.errors != null && help.errors.size() > 0) {
|
||||||
builder.append(" On failure returns:\n");
|
builder.append(" ");
|
||||||
|
builder.append(this.translator.translate(TRANSLATION_CONTEXT_PATH, "help: failure responses", "On failure returns:"));
|
||||||
|
builder.append("\n");
|
||||||
for(String content : help.errors) {
|
for(String content : help.errors) {
|
||||||
builder.append(" " + content + "\n");
|
builder.append(" " + content + "\n");
|
||||||
}
|
}
|
||||||
|
@ -117,4 +117,5 @@ public enum ApiError {
|
|||||||
int getStatus() {
|
int getStatus() {
|
||||||
return this.status;
|
return this.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -101,16 +101,16 @@ public class ApiErrorFactory {
|
|||||||
// this.errorMessages.put(ApiError.NAME_FOR_SALE, createErrorMessageEntry(ApiError.NAME_FOR_SALE, NameResult.NAME_FOR_SALE.getStatusMessage()));
|
// this.errorMessages.put(ApiError.NAME_FOR_SALE, createErrorMessageEntry(ApiError.NAME_FOR_SALE, NameResult.NAME_FOR_SALE.getStatusMessage()));
|
||||||
// this.errorMessages.put(ApiError.NAME_WITH_SPACE, createErrorMessageEntry(ApiError.NAME_WITH_SPACE, NameResult.NAME_WITH_SPACE.getStatusMessage()));
|
// this.errorMessages.put(ApiError.NAME_WITH_SPACE, createErrorMessageEntry(ApiError.NAME_WITH_SPACE, NameResult.NAME_WITH_SPACE.getStatusMessage()));
|
||||||
//AT
|
//AT
|
||||||
this.errorMessages.put(ApiError.INVALID_CREATION_BYTES, createErrorMessageEntry(ApiError.INVALID_CREATION_BYTES, "error in creation bytes"));
|
|
||||||
// TODO
|
// TODO
|
||||||
// this.errorMessages.put(ApiError.INVALID_DESC_LENGTH, createErrorMessageEntry(ApiError.INVALID_DESC_LENGTH,
|
// this.errorMessages.put(ApiError.INVALID_DESC_LENGTH, createErrorMessageEntry(ApiError.INVALID_DESC_LENGTH,
|
||||||
// "invalid description length. max length ${MAX_LENGTH}",
|
// "invalid description length. max length ${MAX_LENGTH}",
|
||||||
// new AbstractMap.SimpleEntry<String, Object>("MAX_LENGTH", AT_Constants.DESC_MAX_LENGTH));
|
// new AbstractMap.SimpleEntry<String, Object>("MAX_LENGTH", AT_Constants.DESC_MAX_LENGTH));
|
||||||
this.errorMessages.put(ApiError.EMPTY_CODE, createErrorMessageEntry(ApiError.EMPTY_CODE, "code is empty"));
|
this.errorMessages.put(ApiError.EMPTY_CODE, createErrorMessageEntry(ApiError.EMPTY_CODE, "code is empty"));
|
||||||
this.errorMessages.put(ApiError.DATA_SIZE, createErrorMessageEntry(ApiError.DATA_SIZE, "invalid data length"));
|
this.errorMessages.put(ApiError.DATA_SIZE, createErrorMessageEntry(ApiError.DATA_SIZE, "invalid data length"));
|
||||||
|
this.errorMessages.put(ApiError.NULL_PAGES, createErrorMessageEntry(ApiError.NULL_PAGES, "invalid pages"));
|
||||||
this.errorMessages.put(ApiError.INVALID_TYPE_LENGTH, createErrorMessageEntry(ApiError.INVALID_TYPE_LENGTH, "invalid type length"));
|
this.errorMessages.put(ApiError.INVALID_TYPE_LENGTH, createErrorMessageEntry(ApiError.INVALID_TYPE_LENGTH, "invalid type length"));
|
||||||
this.errorMessages.put(ApiError.INVALID_TAGS_LENGTH, createErrorMessageEntry(ApiError.INVALID_TAGS_LENGTH, "invalid tags length"));
|
this.errorMessages.put(ApiError.INVALID_TAGS_LENGTH, createErrorMessageEntry(ApiError.INVALID_TAGS_LENGTH, "invalid tags length"));
|
||||||
this.errorMessages.put(ApiError.NULL_PAGES, createErrorMessageEntry(ApiError.NULL_PAGES, "invalid pages"));
|
this.errorMessages.put(ApiError.INVALID_CREATION_BYTES, createErrorMessageEntry(ApiError.INVALID_CREATION_BYTES, "error in creation bytes"));
|
||||||
|
|
||||||
//BLOG
|
//BLOG
|
||||||
this.errorMessages.put(ApiError.BODY_EMPTY, createErrorMessageEntry(ApiError.BODY_EMPTY, "invalid body it must not be empty"));
|
this.errorMessages.put(ApiError.BODY_EMPTY, createErrorMessageEntry(ApiError.BODY_EMPTY, "invalid body it must not be empty"));
|
||||||
@ -166,8 +166,7 @@ public class ApiErrorFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ApiException createError(ApiError error, Throwable throwable) {
|
public ApiException createError(ApiError error, Throwable throwable) {
|
||||||
Locale locale = Locale.ENGLISH; // default locale
|
return createError(null, error, throwable);
|
||||||
return createError(locale, error, throwable);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ApiException createError(Locale locale, ApiError error, Throwable throwable) {
|
public ApiException createError(Locale locale, ApiError error, Throwable throwable) {
|
||||||
|
@ -44,23 +44,33 @@ public class BlocksResource {
|
|||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Operation(
|
@Operation(
|
||||||
description = "Returns an array of the 50 last blocks generated by your accounts",
|
description = "returns an array of the 50 last blocks generated by your accounts",
|
||||||
extensions = @Extension(name = "translation", properties = {
|
extensions = @Extension(name = "translation", properties = {
|
||||||
@ExtensionProperty(name="path", value="getBlocks"),
|
@ExtensionProperty(name="path", value="GET"),
|
||||||
@ExtensionProperty(name="description.key", value="description")
|
@ExtensionProperty(name="description.key", value="operation:description")
|
||||||
}),
|
}),
|
||||||
responses = {
|
responses = {
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
description = "The blocks"
|
description = "the blocks",
|
||||||
//content = @Content(schema = @Schema(implementation = ???))
|
//content = @Content(schema = @Schema(implementation = ???))
|
||||||
|
extensions = {
|
||||||
|
@Extension(name = "translation", properties = {
|
||||||
|
@ExtensionProperty(name="description.key", value="success_response:description")
|
||||||
|
})
|
||||||
|
}
|
||||||
),
|
),
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
responseCode = "422",
|
responseCode = "422",
|
||||||
description = "Error: 201 - Wallet does not exist",
|
description = "wallet does not exist",
|
||||||
extensions = @Extension(name = "translation", properties = {
|
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class)),
|
||||||
@ExtensionProperty(name="description.key", value="ApiError/201")
|
extensions = {
|
||||||
}),
|
@Extension(properties = {
|
||||||
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class))
|
@ExtensionProperty(name="apiErrorCode", value="201")
|
||||||
|
}),
|
||||||
|
@Extension(name = "translation", properties = {
|
||||||
|
@ExtensionProperty(name="description.key", value="ApiError/201")
|
||||||
|
})
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -73,26 +83,59 @@ public class BlocksResource {
|
|||||||
@GET
|
@GET
|
||||||
@Path("/address/{address}")
|
@Path("/address/{address}")
|
||||||
@Operation(
|
@Operation(
|
||||||
description = "Returns an array of the 50 last blocks generated by a specific address in your wallet",
|
description = "returns an array of the 50 last blocks generated by a specific address in your wallet",
|
||||||
|
extensions = @Extension(name = "translation", properties = {
|
||||||
|
@ExtensionProperty(name="path", value="GET address:address"),
|
||||||
|
@ExtensionProperty(name="description.key", value="operation:description")
|
||||||
|
}),
|
||||||
responses = {
|
responses = {
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
description = "The blocks"
|
description = "the blocks",
|
||||||
//content = @Content(schema = @Schema(implementation = ???))
|
//content = @Content(schema = @Schema(implementation = ???)),
|
||||||
|
extensions = {
|
||||||
|
@Extension(name = "translation", properties = {
|
||||||
|
@ExtensionProperty(name="description.key", value="success_response:description")
|
||||||
|
})
|
||||||
|
}
|
||||||
),
|
),
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
responseCode = "400",
|
responseCode = "400",
|
||||||
description = "102 - Invalid address",
|
description = "invalid address",
|
||||||
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class))
|
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class)),
|
||||||
|
extensions = {
|
||||||
|
@Extension(properties = {
|
||||||
|
@ExtensionProperty(name="apiErrorCode", value="102")
|
||||||
|
}),
|
||||||
|
@Extension(name = "translation", properties = {
|
||||||
|
@ExtensionProperty(name="description.key", value="ApiError/102")
|
||||||
|
})
|
||||||
|
}
|
||||||
),
|
),
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
responseCode = "422",
|
responseCode = "422",
|
||||||
description = "201 - Wallet does not exist",
|
description = "wallet does not exist",
|
||||||
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class))
|
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class)),
|
||||||
|
extensions = {
|
||||||
|
@Extension(properties = {
|
||||||
|
@ExtensionProperty(name="apiErrorCode", value="201")
|
||||||
|
}),
|
||||||
|
@Extension(name = "translation", properties = {
|
||||||
|
@ExtensionProperty(name="description.key", value="ApiError/201")
|
||||||
|
})
|
||||||
|
}
|
||||||
),
|
),
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
responseCode = "422",
|
responseCode = "422",
|
||||||
description = "202 - Address does not exist in wallet",
|
description = "address does not exist in wallet",
|
||||||
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class))
|
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class)),
|
||||||
|
extensions = {
|
||||||
|
@Extension(properties = {
|
||||||
|
@ExtensionProperty(name="apiErrorCode", value="202")
|
||||||
|
}),
|
||||||
|
@Extension(name = "translation", properties = {
|
||||||
|
@ExtensionProperty(name="description.key", value="ApiError/202")
|
||||||
|
})
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -105,21 +148,46 @@ public class BlocksResource {
|
|||||||
@GET
|
@GET
|
||||||
@Path("/{signature}")
|
@Path("/{signature}")
|
||||||
@Operation(
|
@Operation(
|
||||||
description = "Returns the block that matches the given signature",
|
description = "returns the block that matches the given signature",
|
||||||
|
extensions = @Extension(name = "translation", properties = {
|
||||||
|
@ExtensionProperty(name="path", value="GET signature"),
|
||||||
|
@ExtensionProperty(name="description.key", value="operation:description")
|
||||||
|
}),
|
||||||
responses = {
|
responses = {
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
description = "The block"
|
description = "the block",
|
||||||
//content = @Content(schema = @Schema(implementation = ???))
|
//content = @Content(schema = @Schema(implementation = ???)),
|
||||||
|
extensions = {
|
||||||
|
@Extension(name = "translation", properties = {
|
||||||
|
@ExtensionProperty(name="description.key", value="success_response:description")
|
||||||
|
})
|
||||||
|
}
|
||||||
),
|
),
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
responseCode = "400",
|
responseCode = "400",
|
||||||
description = "101 - Invalid signature",
|
description = "invalid signature",
|
||||||
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class))
|
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class)),
|
||||||
|
extensions = {
|
||||||
|
@Extension(properties = {
|
||||||
|
@ExtensionProperty(name="apiErrorCode", value="101")
|
||||||
|
}),
|
||||||
|
@Extension(name = "translation", properties = {
|
||||||
|
@ExtensionProperty(name="description.key", value="ApiError/101")
|
||||||
|
})
|
||||||
|
}
|
||||||
),
|
),
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
responseCode = "422",
|
responseCode = "422",
|
||||||
description = "301 - Block does not exist",
|
description = "block does not exist",
|
||||||
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class))
|
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class)),
|
||||||
|
extensions = {
|
||||||
|
@Extension(properties = {
|
||||||
|
@ExtensionProperty(name="apiErrorCode", value="301")
|
||||||
|
}),
|
||||||
|
@Extension(name = "translation", properties = {
|
||||||
|
@ExtensionProperty(name="description.key", value="ApiError/301")
|
||||||
|
})
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -132,11 +200,20 @@ public class BlocksResource {
|
|||||||
@GET
|
@GET
|
||||||
@Path("/first")
|
@Path("/first")
|
||||||
@Operation(
|
@Operation(
|
||||||
description = "Returns the genesis block",
|
description = "returns the genesis block",
|
||||||
|
extensions = @Extension(name = "translation", properties = {
|
||||||
|
@ExtensionProperty(name="path", value="GET first"),
|
||||||
|
@ExtensionProperty(name="description.key", value="operation:description")
|
||||||
|
}),
|
||||||
responses = {
|
responses = {
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
description = "The block"
|
description = "the block",
|
||||||
//content = @Content(schema = @Schema(implementation = ???))
|
//content = @Content(schema = @Schema(implementation = ???)),
|
||||||
|
extensions = {
|
||||||
|
@Extension(name = "translation", properties = {
|
||||||
|
@ExtensionProperty(name="description.key", value="success_response:description")
|
||||||
|
})
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -149,11 +226,20 @@ public class BlocksResource {
|
|||||||
@GET
|
@GET
|
||||||
@Path("/last")
|
@Path("/last")
|
||||||
@Operation(
|
@Operation(
|
||||||
description = "Returns the last valid block",
|
description = "returns the last valid block",
|
||||||
|
extensions = @Extension(name = "translation", properties = {
|
||||||
|
@ExtensionProperty(name="path", value="GET last"),
|
||||||
|
@ExtensionProperty(name="description.key", value="operation:description")
|
||||||
|
}),
|
||||||
responses = {
|
responses = {
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
description = "The block"
|
description = "the block",
|
||||||
//content = @Content(schema = @Schema(implementation = ???))
|
//content = @Content(schema = @Schema(implementation = ???)),
|
||||||
|
extensions = {
|
||||||
|
@Extension(name = "translation", properties = {
|
||||||
|
@ExtensionProperty(name="description.key", value="success_response:description")
|
||||||
|
})
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -166,21 +252,46 @@ public class BlocksResource {
|
|||||||
@GET
|
@GET
|
||||||
@Path("/child/{signature}")
|
@Path("/child/{signature}")
|
||||||
@Operation(
|
@Operation(
|
||||||
description = "Returns the child block of the block that matches the given signature",
|
description = "returns the child block of the block that matches the given signature",
|
||||||
|
extensions = @Extension(name = "translation", properties = {
|
||||||
|
@ExtensionProperty(name="path", value="GET child:signature"),
|
||||||
|
@ExtensionProperty(name="description.key", value="operation:description")
|
||||||
|
}),
|
||||||
responses = {
|
responses = {
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
description = "The block"
|
description = "the block",
|
||||||
//content = @Content(schema = @Schema(implementation = ???))
|
//content = @Content(schema = @Schema(implementation = ???)),
|
||||||
|
extensions = {
|
||||||
|
@Extension(name = "translation", properties = {
|
||||||
|
@ExtensionProperty(name="description.key", value="success_response:description")
|
||||||
|
})
|
||||||
|
}
|
||||||
),
|
),
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
responseCode = "400",
|
responseCode = "400",
|
||||||
description = "101 - Invalid signature",
|
description = "invalid signature",
|
||||||
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class))
|
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class)),
|
||||||
|
extensions = {
|
||||||
|
@Extension(properties = {
|
||||||
|
@ExtensionProperty(name="apiErrorCode", value="101")
|
||||||
|
}),
|
||||||
|
@Extension(name = "translation", properties = {
|
||||||
|
@ExtensionProperty(name="description.key", value="ApiError/101")
|
||||||
|
})
|
||||||
|
}
|
||||||
),
|
),
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
responseCode = "422",
|
responseCode = "422",
|
||||||
description = "301 - Block does not exist",
|
description = "block does not exist",
|
||||||
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class))
|
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class)),
|
||||||
|
extensions = {
|
||||||
|
@Extension(properties = {
|
||||||
|
@ExtensionProperty(name="apiErrorCode", value="301")
|
||||||
|
}),
|
||||||
|
@Extension(name = "translation", properties = {
|
||||||
|
@ExtensionProperty(name="description.key", value="ApiError/301")
|
||||||
|
})
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -193,11 +304,20 @@ public class BlocksResource {
|
|||||||
@GET
|
@GET
|
||||||
@Path("/generatingbalance")
|
@Path("/generatingbalance")
|
||||||
@Operation(
|
@Operation(
|
||||||
description = "Calculates the generating balance of the block that will follow the last block",
|
description = "calculates the generating balance of the block that will follow the last block",
|
||||||
|
extensions = @Extension(name = "translation", properties = {
|
||||||
|
@ExtensionProperty(name="path", value="GET generatingbalance"),
|
||||||
|
@ExtensionProperty(name="description.key", value="operation:description")
|
||||||
|
}),
|
||||||
responses = {
|
responses = {
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
description = "The generating balance",
|
description = "the generating balance",
|
||||||
content = @Content(schema = @Schema(implementation = long.class))
|
content = @Content(schema = @Schema(implementation = long.class)),
|
||||||
|
extensions = {
|
||||||
|
@Extension(name = "translation", properties = {
|
||||||
|
@ExtensionProperty(name="description.key", value="success_response:description")
|
||||||
|
})
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -210,21 +330,46 @@ public class BlocksResource {
|
|||||||
@GET
|
@GET
|
||||||
@Path("/generatingbalance/{signature}")
|
@Path("/generatingbalance/{signature}")
|
||||||
@Operation(
|
@Operation(
|
||||||
description = "Calculates the generating balance of the block that will follow the block that matches the signature",
|
description = "calculates the generating balance of the block that will follow the block that matches the signature",
|
||||||
|
extensions = @Extension(name = "translation", properties = {
|
||||||
|
@ExtensionProperty(name="path", value="GET generatingbalance:signature"),
|
||||||
|
@ExtensionProperty(name="description.key", value="operation:description")
|
||||||
|
}),
|
||||||
responses = {
|
responses = {
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
description = "The block",
|
description = "the block",
|
||||||
content = @Content(schema = @Schema(implementation = long.class))
|
content = @Content(schema = @Schema(implementation = long.class)),
|
||||||
|
extensions = {
|
||||||
|
@Extension(name = "translation", properties = {
|
||||||
|
@ExtensionProperty(name="description.key", value="success_response:description")
|
||||||
|
})
|
||||||
|
}
|
||||||
),
|
),
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
responseCode = "400",
|
responseCode = "400",
|
||||||
description = "101 - Invalid signature",
|
description = "invalid signature",
|
||||||
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class))
|
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class)),
|
||||||
|
extensions = {
|
||||||
|
@Extension(properties = {
|
||||||
|
@ExtensionProperty(name="apiErrorCode", value="101")
|
||||||
|
}),
|
||||||
|
@Extension(name = "translation", properties = {
|
||||||
|
@ExtensionProperty(name="description.key", value="ApiError/101")
|
||||||
|
})
|
||||||
|
}
|
||||||
),
|
),
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
responseCode = "422",
|
responseCode = "422",
|
||||||
description = "301 - Block does not exist",
|
description = "block does not exist",
|
||||||
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class))
|
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class)),
|
||||||
|
extensions = {
|
||||||
|
@Extension(properties = {
|
||||||
|
@ExtensionProperty(name="apiErrorCode", value="301")
|
||||||
|
}),
|
||||||
|
@Extension(name = "translation", properties = {
|
||||||
|
@ExtensionProperty(name="description.key", value="ApiError/301")
|
||||||
|
})
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -237,11 +382,20 @@ public class BlocksResource {
|
|||||||
@GET
|
@GET
|
||||||
@Path("/time")
|
@Path("/time")
|
||||||
@Operation(
|
@Operation(
|
||||||
description = "Calculates the time it should take for the network to generate the next block",
|
description = "calculates the time it should take for the network to generate the next block",
|
||||||
|
extensions = @Extension(name = "translation", properties = {
|
||||||
|
@ExtensionProperty(name="path", value="GET time"),
|
||||||
|
@ExtensionProperty(name="description.key", value="operation:description")
|
||||||
|
}),
|
||||||
responses = {
|
responses = {
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
description = "The time", // in seconds?
|
description = "the time", // in seconds?
|
||||||
content = @Content(schema = @Schema(implementation = long.class))
|
content = @Content(schema = @Schema(implementation = long.class)),
|
||||||
|
extensions = {
|
||||||
|
@Extension(name = "translation", properties = {
|
||||||
|
@ExtensionProperty(name="description.key", value="success_response:description")
|
||||||
|
})
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -254,11 +408,20 @@ public class BlocksResource {
|
|||||||
@GET
|
@GET
|
||||||
@Path("/time/{generatingbalance}")
|
@Path("/time/{generatingbalance}")
|
||||||
@Operation(
|
@Operation(
|
||||||
description = "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",
|
description = "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",
|
||||||
|
extensions = @Extension(name = "translation", properties = {
|
||||||
|
@ExtensionProperty(name="path", value="GET time:generatingbalance"),
|
||||||
|
@ExtensionProperty(name="description.key", value="operation:description")
|
||||||
|
}),
|
||||||
responses = {
|
responses = {
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
description = "The time", // in seconds?
|
description = "the time", // in seconds?
|
||||||
content = @Content(schema = @Schema(implementation = long.class))
|
content = @Content(schema = @Schema(implementation = long.class)),
|
||||||
|
extensions = {
|
||||||
|
@Extension(name = "translation", properties = {
|
||||||
|
@ExtensionProperty(name="description.key", value="success_response:description")
|
||||||
|
})
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -271,11 +434,20 @@ public class BlocksResource {
|
|||||||
@GET
|
@GET
|
||||||
@Path("/height")
|
@Path("/height")
|
||||||
@Operation(
|
@Operation(
|
||||||
description = "Returns the block height of the last block.",
|
description = "returns the block height of the last block.",
|
||||||
|
extensions = @Extension(name = "translation", properties = {
|
||||||
|
@ExtensionProperty(name="path", value="GET height"),
|
||||||
|
@ExtensionProperty(name="description.key", value="operation:description")
|
||||||
|
}),
|
||||||
responses = {
|
responses = {
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
description = "The height",
|
description = "the height",
|
||||||
content = @Content(schema = @Schema(implementation = int.class))
|
content = @Content(schema = @Schema(implementation = int.class)),
|
||||||
|
extensions = {
|
||||||
|
@Extension(name = "translation", properties = {
|
||||||
|
@ExtensionProperty(name="description.key", value="success_response:description")
|
||||||
|
})
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -292,21 +464,46 @@ public class BlocksResource {
|
|||||||
@GET
|
@GET
|
||||||
@Path("/height/{signature}")
|
@Path("/height/{signature}")
|
||||||
@Operation(
|
@Operation(
|
||||||
description = "Returns the block height of the block that matches the given signature",
|
description = "returns the block height of the block that matches the given signature",
|
||||||
|
extensions = @Extension(name = "translation", properties = {
|
||||||
|
@ExtensionProperty(name="path", value="GET height:signature"),
|
||||||
|
@ExtensionProperty(name="description.key", value="operation:description")
|
||||||
|
}),
|
||||||
responses = {
|
responses = {
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
description = "The height",
|
description = "the height",
|
||||||
content = @Content(schema = @Schema(implementation = int.class))
|
content = @Content(schema = @Schema(implementation = int.class)),
|
||||||
|
extensions = {
|
||||||
|
@Extension(name = "translation", properties = {
|
||||||
|
@ExtensionProperty(name="description.key", value="success_response:description")
|
||||||
|
})
|
||||||
|
}
|
||||||
),
|
),
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
responseCode = "400",
|
responseCode = "400",
|
||||||
description = "101 - Invalid signature",
|
description = "invalid signature",
|
||||||
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class))
|
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class)),
|
||||||
|
extensions = {
|
||||||
|
@Extension(properties = {
|
||||||
|
@ExtensionProperty(name="apiErrorCode", value="101")
|
||||||
|
}),
|
||||||
|
@Extension(name = "translation", properties = {
|
||||||
|
@ExtensionProperty(name="description.key", value="ApiError/101")
|
||||||
|
})
|
||||||
|
}
|
||||||
),
|
),
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
responseCode = "422",
|
responseCode = "422",
|
||||||
description = "301 - Block does not exist",
|
description = "block does not exist",
|
||||||
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class))
|
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class)),
|
||||||
|
extensions = {
|
||||||
|
@Extension(properties = {
|
||||||
|
@ExtensionProperty(name="apiErrorCode", value="301")
|
||||||
|
}),
|
||||||
|
@Extension(name = "translation", properties = {
|
||||||
|
@ExtensionProperty(name="description.key", value="ApiError/301")
|
||||||
|
})
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -319,16 +516,33 @@ public class BlocksResource {
|
|||||||
@GET
|
@GET
|
||||||
@Path("/byheight/{height}")
|
@Path("/byheight/{height}")
|
||||||
@Operation(
|
@Operation(
|
||||||
description = "Returns the block whith given height",
|
description = "returns the block whith given height",
|
||||||
|
extensions = @Extension(name = "translation", properties = {
|
||||||
|
@ExtensionProperty(name="path", value="GET byheight:height"),
|
||||||
|
@ExtensionProperty(name="description.key", value="operation:description")
|
||||||
|
}),
|
||||||
responses = {
|
responses = {
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
description = "The block"
|
description = "the block",
|
||||||
//content = @Content(schema = @Schema(implementation = ???))
|
//content = @Content(schema = @Schema(implementation = ???)),
|
||||||
|
extensions = {
|
||||||
|
@Extension(name = "translation", properties = {
|
||||||
|
@ExtensionProperty(name="description.key", value="success_response:description")
|
||||||
|
})
|
||||||
|
}
|
||||||
),
|
),
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
responseCode = "422",
|
responseCode = "422",
|
||||||
description = "301 - Block does not exist",
|
description = "block does not exist",
|
||||||
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class))
|
content = @Content(schema = @Schema(implementation = ApiErrorMessage.class)),
|
||||||
|
extensions = {
|
||||||
|
@Extension(properties = {
|
||||||
|
@ExtensionProperty(name="apiErrorCode", value="301")
|
||||||
|
}),
|
||||||
|
@Extension(name = "translation", properties = {
|
||||||
|
@ExtensionProperty(name="description.key", value="ApiError/301")
|
||||||
|
})
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
74
src/api/Constants.java
Normal file
74
src/api/Constants.java
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
package api;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.models.Operation;
|
||||||
|
import io.swagger.v3.oas.models.PathItem;
|
||||||
|
import io.swagger.v3.oas.models.info.Info;
|
||||||
|
import io.swagger.v3.oas.models.responses.ApiResponse;
|
||||||
|
import static java.util.Arrays.asList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
class Constants {
|
||||||
|
|
||||||
|
public static final String TRANSLATION_EXTENSION_NAME = "translation";
|
||||||
|
public static final String TRANSLATION_PATH_EXTENSION_NAME = "path";
|
||||||
|
|
||||||
|
public static final String TRANSLATION_ANNOTATION_DESCRIPTION_KEY = "description.key";
|
||||||
|
public static final String TRANSLATION_ANNOTATION_SUMMARY_KEY = "summary.key";
|
||||||
|
public static final String TRANSLATION_ANNOTATION_TITLE_KEY = "title.key";
|
||||||
|
public static final String TRANSLATION_ANNOTATION_TERMS_OF_SERVICE_KEY = "termsOfService.key";
|
||||||
|
|
||||||
|
public static final String API_ERROR_CODE_EXTENSION_NAME = "apiErrorCode";
|
||||||
|
|
||||||
|
|
||||||
|
public static final List<TranslatableProperty<Info>> TRANSLATABLE_INFO_PROPERTIES = asList(
|
||||||
|
new TranslatableProperty<Info>() {
|
||||||
|
@Override public String keyName() { return TRANSLATION_ANNOTATION_DESCRIPTION_KEY; }
|
||||||
|
@Override public void setValue(Info item, String translation) { item.setDescription(translation); }
|
||||||
|
@Override public String getValue(Info item) { return item.getDescription(); }
|
||||||
|
},
|
||||||
|
new TranslatableProperty<Info>() {
|
||||||
|
@Override public String keyName() { return TRANSLATION_ANNOTATION_TITLE_KEY; }
|
||||||
|
@Override public void setValue(Info item, String translation) { item.setTitle(translation); }
|
||||||
|
@Override public String getValue(Info item) { return item.getTitle(); }
|
||||||
|
},
|
||||||
|
new TranslatableProperty<Info>() {
|
||||||
|
@Override public String keyName() { return TRANSLATION_ANNOTATION_TERMS_OF_SERVICE_KEY; }
|
||||||
|
@Override public void setValue(Info item, String translation) { item.setTermsOfService(translation); }
|
||||||
|
@Override public String getValue(Info item) { return item.getTermsOfService(); }
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final List<TranslatableProperty<PathItem>> TRANSLATABLE_PATH_ITEM_PROPERTIES = asList(
|
||||||
|
new TranslatableProperty<PathItem>() {
|
||||||
|
@Override public String keyName() { return TRANSLATION_ANNOTATION_DESCRIPTION_KEY; }
|
||||||
|
@Override public void setValue(PathItem item, String translation) { item.setDescription(translation); }
|
||||||
|
@Override public String getValue(PathItem item) { return item.getDescription(); }
|
||||||
|
},
|
||||||
|
new TranslatableProperty<PathItem>() {
|
||||||
|
@Override public String keyName() { return TRANSLATION_ANNOTATION_SUMMARY_KEY; }
|
||||||
|
@Override public void setValue(PathItem item, String translation) { item.setSummary(translation); }
|
||||||
|
@Override public String getValue(PathItem item) { return item.getSummary(); }
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final List<TranslatableProperty<Operation>> TRANSLATABLE_OPERATION_PROPERTIES = asList(
|
||||||
|
new TranslatableProperty<Operation>() {
|
||||||
|
@Override public String keyName() { return TRANSLATION_ANNOTATION_DESCRIPTION_KEY; }
|
||||||
|
@Override public void setValue(Operation item, String translation) { item.setDescription(translation); }
|
||||||
|
@Override public String getValue(Operation item) { return item.getDescription(); }
|
||||||
|
},
|
||||||
|
new TranslatableProperty<Operation>() {
|
||||||
|
@Override public String keyName() { return TRANSLATION_ANNOTATION_SUMMARY_KEY; }
|
||||||
|
@Override public void setValue(Operation item, String translation) { item.setSummary(translation); }
|
||||||
|
@Override public String getValue(Operation item) { return item.getSummary(); }
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final List<TranslatableProperty<ApiResponse>> TRANSLATABLE_API_RESPONSE_PROPERTIES = asList(
|
||||||
|
new TranslatableProperty<ApiResponse>() {
|
||||||
|
@Override public String keyName() { return TRANSLATION_ANNOTATION_DESCRIPTION_KEY; }
|
||||||
|
@Override public void setValue(ApiResponse item, String translation) { item.setDescription(translation); }
|
||||||
|
@Override public String getValue(ApiResponse item) { return item.getDescription(); }
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
7
src/api/TranslatableProperty.java
Normal file
7
src/api/TranslatableProperty.java
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package api;
|
||||||
|
|
||||||
|
interface TranslatableProperty<T> {
|
||||||
|
public String keyName();
|
||||||
|
public void setValue(T item, String translation);
|
||||||
|
public String getValue(T item);
|
||||||
|
}
|
@ -1,7 +1,6 @@
|
|||||||
package globalization;
|
package globalization;
|
||||||
|
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import javax.xml.stream.XMLStreamException;
|
|
||||||
|
|
||||||
public class ContextPaths {
|
public class ContextPaths {
|
||||||
|
|
||||||
@ -18,6 +17,8 @@ public class ContextPaths {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static String combinePaths(String left, String right) {
|
public static String combinePaths(String left, String right) {
|
||||||
|
left = (left != null) ? left : "";
|
||||||
|
right = (right != null) ? right : "";
|
||||||
return Paths.get("/", left, right).normalize().toString();
|
return Paths.get("/", left, right).normalize().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ import javax.xml.stream.XMLEventReader;
|
|||||||
import javax.xml.stream.XMLInputFactory;
|
import javax.xml.stream.XMLInputFactory;
|
||||||
import javax.xml.stream.XMLStreamException;
|
import javax.xml.stream.XMLStreamException;
|
||||||
import javax.xml.stream.events.*;
|
import javax.xml.stream.events.*;
|
||||||
|
import org.apache.commons.text.StringEscapeUtils;
|
||||||
|
|
||||||
public class TranslationXmlStreamReader {
|
public class TranslationXmlStreamReader {
|
||||||
|
|
||||||
@ -183,7 +184,7 @@ public class TranslationXmlStreamReader {
|
|||||||
path = ContextPaths.combinePaths(state.path, value);
|
path = ContextPaths.combinePaths(state.path, value);
|
||||||
break;
|
break;
|
||||||
case TRANSLATION_TEMPLATE_ATTRIBUTE_NAME:
|
case TRANSLATION_TEMPLATE_ATTRIBUTE_NAME:
|
||||||
template = value;
|
template = unescape(value);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new javax.xml.stream.XMLStreamException("Unexpected attribute: " + name);
|
throw new javax.xml.stream.XMLStreamException("Unexpected attribute: " + name);
|
||||||
@ -211,6 +212,10 @@ public class TranslationXmlStreamReader {
|
|||||||
result.add(new TranslationEntry(state.locale, path, template));
|
result.add(new TranslationEntry(state.locale, path, template));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String unescape(String value) {
|
||||||
|
return StringEscapeUtils.unescapeJava(value);
|
||||||
|
}
|
||||||
|
|
||||||
private void assureIsValidPathExtension(String value) throws XMLStreamException {
|
private void assureIsValidPathExtension(String value) throws XMLStreamException {
|
||||||
if(ContextPaths.containsParentReference(value))
|
if(ContextPaths.containsParentReference(value))
|
||||||
throw new javax.xml.stream.XMLStreamException("Parent reference .. is not allowed");
|
throw new javax.xml.stream.XMLStreamException("Parent reference .. is not allowed");
|
||||||
|
@ -94,32 +94,61 @@ public class Translator {
|
|||||||
return translate(locale, contextPath, templateKey, map);
|
return translate(locale, contextPath, templateKey, map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String translate(String contextPath, String templateKey, AbstractMap.Entry<String, Object>... templateValues) {
|
||||||
|
Map<String, Object> map = createMap(templateValues);
|
||||||
|
return translate(contextPath, templateKey, map);
|
||||||
|
}
|
||||||
|
|
||||||
public String translate(Locale locale, String contextPath, String templateKey, Map<String, Object> templateValues) {
|
public String translate(Locale locale, String contextPath, String templateKey, Map<String, Object> templateValues) {
|
||||||
return translate(locale, contextPath, templateKey, null, templateValues);
|
return translate(locale, contextPath, templateKey, null, templateValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String translate(String contextPath, String templateKey, Map<String, Object> templateValues) {
|
||||||
|
return translate(contextPath, templateKey, null, templateValues);
|
||||||
|
}
|
||||||
|
|
||||||
public String translate(Locale locale, String contextPath, String templateKey, String defaultTemplate, AbstractMap.Entry<String, Object>... templateValues) {
|
public String translate(Locale locale, String contextPath, String templateKey, String defaultTemplate, AbstractMap.Entry<String, Object>... templateValues) {
|
||||||
Map<String, Object> map = createMap(templateValues);
|
Map<String, Object> map = createMap(templateValues);
|
||||||
return translate(locale, contextPath, templateKey, defaultTemplate, map);
|
return translate(locale, contextPath, templateKey, defaultTemplate, map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String translate(String contextPath, String templateKey, String defaultTemplate, AbstractMap.Entry<String, Object>... templateValues) {
|
||||||
|
Map<String, Object> map = createMap(templateValues);
|
||||||
|
return translate(contextPath, templateKey, defaultTemplate, map);
|
||||||
|
}
|
||||||
|
|
||||||
public String translate(Locale locale, String contextPath, String templateKey, String defaultTemplate, Map<String, Object> templateValues) {
|
public String translate(Locale locale, String contextPath, String templateKey, String defaultTemplate, Map<String, Object> templateValues) {
|
||||||
// look for requested language
|
// look for requested language
|
||||||
String template = getTemplateFromNearestPath(locale, contextPath, templateKey);
|
String template = null;
|
||||||
|
if(locale != null)
|
||||||
|
template = getTemplateFromNearestPath(locale, contextPath, templateKey);
|
||||||
|
|
||||||
if(template == null) {
|
if(template != null)
|
||||||
// scan default languages
|
return substitute(template, templateValues);
|
||||||
for(String language : this.settings().translationsDefaultLocales()) {
|
|
||||||
Locale defaultLocale = Locale.forLanguageTag(language);
|
return translate(contextPath, templateKey, defaultTemplate, templateValues);
|
||||||
template = getTemplateFromNearestPath(defaultLocale, contextPath, templateKey);
|
}
|
||||||
if(template != null)
|
|
||||||
break;
|
public String translate(String contextPath, String templateKey, String defaultTemplate, Map<String, Object> templateValues) {
|
||||||
}
|
// scan default languages
|
||||||
|
String template = null;
|
||||||
|
for(String language : this.settings().translationsDefaultLocales()) {
|
||||||
|
Locale defaultLocale = Locale.forLanguageTag(language);
|
||||||
|
template = getTemplateFromNearestPath(defaultLocale, contextPath, templateKey);
|
||||||
|
if(template != null)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(template == null)
|
if(template == null)
|
||||||
template = defaultTemplate; // fallback template
|
template = defaultTemplate; // fallback template
|
||||||
|
|
||||||
|
return substitute(template, templateValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String substitute(String template, Map<String, Object> templateValues) {
|
||||||
|
if(templateValues == null)
|
||||||
|
return template;
|
||||||
|
|
||||||
StringSubstitutor sub = new StringSubstitutor(templateValues);
|
StringSubstitutor sub = new StringSubstitutor(templateValues);
|
||||||
String result = sub.replace(template);
|
String result = sub.replace(template);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user