-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Added Translation.kt * Added TranslationManager.kt * Added TranslationManagerTest.kt * Updated build.gradle * TranslationManager is initialized on module enable!
- Loading branch information
Showing
6 changed files
with
252 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10 changes: 10 additions & 0 deletions
10
src/main/kotlin/xyz/theprogramsrc/translationsmodule/Main.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package xyz.theprogramsrc.translationsmodule | ||
|
||
import xyz.theprogramsrc.simplecoreapi.global.module.Module | ||
|
||
class Main: Module() { | ||
|
||
override fun onEnable() { | ||
TranslationManager() | ||
} | ||
} |
125 changes: 125 additions & 0 deletions
125
src/main/kotlin/xyz/theprogramsrc/translationsmodule/TranslationManager.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
package xyz.theprogramsrc.translationsmodule | ||
|
||
import xyz.theprogramsrc.filesmodule.config.YmlConfig | ||
import xyz.theprogramsrc.filesmodule.utils.folder | ||
import xyz.theprogramsrc.translationsmodule.objects.Translation | ||
import java.io.File | ||
|
||
/** | ||
* Representation of the translation manager. | ||
*/ | ||
class TranslationManager { | ||
|
||
private val translationsCache = mutableMapOf<String, MutableList<Translation>>() | ||
private val cache = mutableMapOf<String, MutableMap<String, MutableMap<String, String>>>() | ||
|
||
companion object { | ||
private val translationSettings = YmlConfig(File(File("plugins/SimpleCoreAPI").folder(), "TranslationSettings.yml")).add("language", "en") | ||
lateinit var instance: TranslationManager | ||
|
||
fun getCurrentLanguage(): String = translationSettings.getStringOrSet("language", "en") | ||
} | ||
|
||
init { | ||
instance = this | ||
loadTranslations() | ||
} | ||
|
||
/** | ||
* Register the given translations to the given group id | ||
* @param group The group (folder) of the translation. Defaults to "common" | ||
* @param translations The translations to register | ||
*/ | ||
fun registerTranslations(group: String = "common", translations: Collection<Translation>) { | ||
val translationsCache = this.translationsCache[group] ?: mutableListOf() | ||
translations.forEach { t -> | ||
if(translationsCache.find { it == t } == null) { | ||
translationsCache.add(t) | ||
} | ||
} | ||
this.translationsCache[group] = translationsCache | ||
loadTranslations() | ||
} | ||
|
||
/** | ||
* Get the translation for the given id in the given language | ||
* @param id The id of the translation | ||
* @param language The language of the translation. Set to null to use the default language. Defaults to null | ||
* @param group The group (folder) of the translation. Defaults to "common" | ||
* @param placeholders The placeholders to replace in the translation. Defaults to empty map | ||
* @return The translation. If the translation is not found, the id is returned | ||
*/ | ||
fun translate(id: String, language: String? = null, group: String = "common", placeholders: Map<String, String> = emptyMap()): String { | ||
val cached = cache[group] ?: return id | ||
var translation = ((cached[language] ?: cached[getCurrentLanguage()] ?: return id)[id] ?: return id) | ||
placeholders.forEach { (key, value) -> | ||
translation = translation.replace("{$key}", value).replace("%$key%", value) | ||
} | ||
return translation | ||
} | ||
|
||
/** | ||
* Loads the translations to the cache. | ||
*/ | ||
fun loadTranslations() { | ||
val translationsFolder = File("translations/").folder() | ||
// First load the default translations | ||
translationsCache.forEach { (group, translations) -> | ||
val folder = File(translationsFolder, group).folder() | ||
translations.forEach { | ||
val languageFile = YmlConfig(File(folder, "${it.language}.lang")) | ||
languageFile.add(it.id, it.defaultValue) | ||
} | ||
} | ||
|
||
// Then load the translations from the language files | ||
(translationsFolder.listFiles() ?: emptyArray()).filter(File::isDirectory).forEach { groupFolder -> | ||
val cached = cache[groupFolder.name] ?: mutableMapOf() | ||
(groupFolder.listFiles() ?: emptyArray()).filter { it.extension == "lang" }.forEach { | ||
val langCache = cached[it.nameWithoutExtension] ?: mutableMapOf() | ||
val cfg = YmlConfig(it) | ||
cfg.keys(true).forEach { id -> | ||
val t = translationsCache[groupFolder.name]?.find { t1 -> t1.id == id } | ||
if(t != null){ | ||
langCache[id] = t.translate(groupFolder.name, it.nameWithoutExtension) | ||
} | ||
} | ||
if(langCache.isNotEmpty()){ | ||
cached[it.nameWithoutExtension] = langCache | ||
} | ||
} | ||
|
||
if(cached.isNotEmpty()) { | ||
cache[groupFolder.name] = cached | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Count the amount of translations | ||
* @param group The group (folder) of the translation. If null it'll count all the groups. Defaults to null | ||
* @param lang The language of the translation. If null it'll count all the languages. Defaults to null | ||
*/ | ||
fun countTranslations(group: String? = null, lang: String? = null): Int { | ||
return if(group == null){ | ||
cache.values.sumOf { | ||
if(lang != null){ | ||
it[lang]?.size ?: 0 | ||
}else { | ||
it.values.sumOf { it2 -> | ||
it2.values.size | ||
} | ||
} | ||
} | ||
} else { | ||
val c = (this.cache[group] ?: return -2) | ||
if(lang != null){ | ||
c[lang]?.size ?: 0 | ||
}else { | ||
c.values.sumOf { it2 -> | ||
it2.values.size | ||
} | ||
} | ||
} | ||
} | ||
} |
58 changes: 58 additions & 0 deletions
58
src/main/kotlin/xyz/theprogramsrc/translationsmodule/objects/Translation.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package xyz.theprogramsrc.translationsmodule.objects | ||
|
||
import xyz.theprogramsrc.filesmodule.config.YmlConfig | ||
import xyz.theprogramsrc.filesmodule.utils.folder | ||
import xyz.theprogramsrc.translationsmodule.TranslationManager | ||
import java.io.File | ||
|
||
/** | ||
* Representation of a translation. | ||
* @param id The id of the translation | ||
* @param defaultValue The default value of the translation. | ||
* @param language The language of the translation. (Defaults to "en") | ||
* @param colors The colors to use in the translation replacing strings. Example (using color '&c'): '**test**' should return '&ctest'. Defaults to empty array. | ||
* @param placeholders The placeholders to use in the translation replacing strings. Example (using placeholder id 'test' and value 'test_value'): '{test}' should return 'test_value'. | ||
* You can use '{}' or '%%' as placeholder identifiers like '{test}' or '%test%'. Defaults to empty map. | ||
*/ | ||
data class Translation(val id: String, val defaultValue: String, val language: String = "en", val colors: Array<String> = emptyArray()) { | ||
|
||
/** | ||
* Translates this [Translation] to the current language. | ||
* @param group The group (folder) of the translation. Defaults to "common" | ||
* @param language The language of the translation. Set to null to use the default language. Defaults to null | ||
* @return The translated string. | ||
*/ | ||
fun translate(group: String = "common", language: String? = null): String { | ||
val file = YmlConfig(File(File("translations/${if(group.endsWith("/")) group else "$group/"}").folder(), (language ?: TranslationManager.getCurrentLanguage()) + ".lang")) | ||
var translation = if(file.has(id)) file.getString(id) else defaultValue | ||
for(i in colors.indices) { | ||
try { | ||
val color = colors[i] | ||
val string = Regex("\\*\\*(.+?)\\*\\*").findAll(translation).first().groupValues[1] | ||
translation = translation.replaceFirst("**$string**", "$color$string") | ||
}catch (_: Exception){} | ||
} | ||
|
||
return translation | ||
} | ||
|
||
override fun equals(other: Any?): Boolean { | ||
if (this === other) return true | ||
if (javaClass != other?.javaClass) return false | ||
|
||
other as Translation | ||
|
||
if (id != other.id) return false | ||
if (defaultValue != other.defaultValue) return false | ||
if (!colors.contentEquals(other.colors)) return false | ||
|
||
return true | ||
} | ||
|
||
override fun hashCode(): Int { | ||
var result = id.hashCode() | ||
result = 31 * result + defaultValue.hashCode() | ||
result = 31 * result + colors.contentHashCode() | ||
return result | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
main=xyz.theprogramsrc.translationsmodule.Main | ||
name=TranslationsModule | ||
description=@description@ | ||
version=@version@ | ||
author=TheProgramSrc | ||
repository-id=translationsmodule | ||
dependencies=FilesModule |
52 changes: 52 additions & 0 deletions
52
src/test/kotlin/xyz/theprogramsrc/translationsmodule/TranslationManagerTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package xyz.theprogramsrc.translationsmodule | ||
|
||
import org.junit.jupiter.api.Assertions.assertEquals | ||
import org.junit.jupiter.api.Test | ||
import xyz.theprogramsrc.translationsmodule.objects.Translation | ||
|
||
internal class TranslationManagerTest { | ||
private val tm = TranslationManager() | ||
private val translations = listOf( | ||
Translation( | ||
id = "id", | ||
defaultValue = "My **colorful** translation!", | ||
language = "en", | ||
colors = arrayOf("&a"), | ||
), | ||
Translation( | ||
id = "id2", | ||
defaultValue = "My **{text}** translation!", | ||
language = "en", | ||
colors = arrayOf("&a"), | ||
), | ||
Translation( | ||
id = "id3", | ||
defaultValue = "My **{text}** translation!", | ||
language = "en", | ||
), | ||
) | ||
|
||
@Test | ||
fun countTest(){ | ||
tm.registerTranslations(translations = translations) | ||
assertEquals(3, tm.countTranslations()) | ||
} | ||
|
||
@Test | ||
fun translationId1Test(){ | ||
tm.registerTranslations(translations = translations) | ||
assertEquals("My &acolorful translation!", tm.translate("id", "en")) | ||
} | ||
|
||
@Test | ||
fun translationId2Test() { | ||
tm.registerTranslations(translations = translations) | ||
assertEquals("My &acolorful translation!", tm.translate("id2", "en", placeholders = mapOf("text" to "colorful"))) | ||
} | ||
|
||
@Test | ||
fun translationId3Test() { | ||
tm.registerTranslations(translations = translations) | ||
assertEquals("My **colorful** translation!", tm.translate("id3", "en", placeholders = mapOf("text" to "colorful"))) | ||
} | ||
} |