Skip to content

Commit

Permalink
Some improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
Alemiz112 committed Mar 21, 2023
1 parent a46e3d2 commit 35f4a21
Show file tree
Hide file tree
Showing 10 changed files with 302 additions and 158 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public static TranslationLibLoader get() {
private final Map<String, TranslationTerm> translationTerms = new ConcurrentHashMap<>();
private final Set<LocalString<?>> activeStrings = Collections.synchronizedSet(new HashSet<>());
private final Set<String> loadedTags = Collections.synchronizedSet(new HashSet<>());
private final List<TranslationTerm> updateQueue = Collections.synchronizedList(new ArrayList<>());
private final Set<TranslationTerm> updateQueue = Collections.synchronizedSet(new HashSet<>());

private ScheduledFuture<?> refreshFuture;

Expand All @@ -56,21 +56,30 @@ protected TranslationLibLoader(LoaderSettings settings) {
}

public void refresh() {
List<TranslationTerm> terms = new ArrayList<>(this.updateQueue);
this.sendTermUpdates();
try {
this.loadTermsByTag(new HashSet<>(this.loadedTags));
this.refreshStrings();
} catch (HttpException e) {
log.error("Exception caught while updating translations: {}", e.statusCode(), e);
} catch (Exception e) {
log.error("Exception caught while updating translations", e);
}
}

public void sendTermUpdates() {
try {
List<TranslationTerm> terms = new ArrayList<>(this.updateQueue);
for (TranslationTerm term : terms) {
RestStatus status = this.getTranslationLibRestApi().termUpdate(term, this.settings.aggressiveUpdates());
if (status.isSuccess()) {
this.updateQueue.clear();
this.updateQueue.remove(term);
} else {
log.warn("Service responded to an update with error: {} cause={}", status.getMessage(), status.getError());
}
}

this.loadTermsByTag(new HashSet<>(this.loadedTags));
this.refreshStrings();
} catch (HttpException e) {
log.error("Exception caught while updating translations: {}", e.statusCode(), e);
log.error("Exception caught while sending term updates: {}", e.statusCode(), e);
} catch (Exception e) {
log.error("Exception caught while updating translations", e);
}
Expand All @@ -80,9 +89,13 @@ public void loadTermsByTag(Collection<String> tags) {
this.clearAllTerms();
for (String tag : tags) {
log.info("Loading terms with tag {}...", tag);
Collection<TranslationTerm> terms = Arrays.asList(this.getTranslationLibRestApi().exportTerms(tag));
this.loadTerms(terms, false);
this.loadedTags.add(tag);
try {
TranslationTerm[] terms = this.getTranslationLibRestApi().exportTerms(tag);
this.loadTerms(Arrays.asList(terms), false);
this.loadedTags.add(tag);
} catch (HttpException e) {
throw new IllegalStateException("Failed to load terms with tag " + tag, e);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import io.avaje.http.client.HttpClient;
import io.avaje.http.client.HttpClientRequest;
import io.avaje.http.client.RequestIntercept;
import io.avaje.http.client.SimpleRetryHandler;
import io.avaje.http.client.gson.GsonBodyAdapter;
import lombok.RequiredArgsConstructor;

Expand All @@ -27,6 +28,7 @@ public void beforeRequest(HttpClientRequest request) {
request.header("auth", token);
}
})
.retryHandler(new SimpleRetryHandler(3, 1000, 0))
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,51 +2,17 @@

import eu.mizerak.alemiz.translationlib.common.TranslationLibLoader;
import eu.mizerak.alemiz.translationlib.common.structure.TranslationTerm;
import lombok.Getter;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Locale;
import java.util.function.Function;

public class LocalString<T> {
private static final Map<StringFormatter, FormatterHandler> formatters = new ConcurrentHashMap<>();
private static final Map<Class<?>, TranslationContext.Factory<?>> contextFactories = new ConcurrentHashMap<>();
public interface LocalString<T> {

public static void registerFormatter(StringFormatter formatter) {
formatters.put(formatter, new FormatterHandler(formatter));
}

public static void unregisterFormatter(StringFormatter formatter) {
formatters.remove(formatter);
}

public static void registerContextFactory(Class<?> clazz, TranslationContext.Factory<?> factory) {
contextFactories.put(clazz, factory);
}

public static void unregisterContextFactory(Class<?> clazz) {
contextFactories.remove(clazz);
}


@Getter
private final String key;
private final TranslationLibLoader loader;

@Getter
private final String fallbackMessage;

@Getter
private TranslationTerm term;
private final Map<Locale, String> formatted = new ConcurrentHashMap<>();

private final Map<String, Function<TranslationContext<T>, String>> arguments = new TreeMap<>();

public static <T> LocalString<T> from(String key, String defaultText) {
static <T> LocalString<T> from(String key, String defaultText) {
return from(key, defaultText, TranslationLibLoader.get());
}

public static <T> LocalString<T> from(String key, String defaultText, TranslationLibLoader loader) {
static <T> LocalString<T> from(String key, String defaultText, TranslationLibLoader loader) {
TranslationTerm term = loader.getTranslationterm(key);
if (term == null) {
term = TranslationTerm.createEmpty(key, defaultText, loader.getDefaultLocale());
Expand All @@ -57,104 +23,35 @@ public static <T> LocalString<T> from(String key, String defaultText, Translatio
throw new IllegalStateException("Term " + key + " has no default translation");
}
}
return new LocalString<>(key, term, loader, defaultText);
LocalStringBase<T> string = new LocalStringImpl<>(key, term, loader, defaultText);
string.enableReload(true);
return string;
}

private LocalString(String key, TranslationTerm term, TranslationLibLoader loader, String fallbackMessage) {
this.key = key;
this.loader = loader;
this.term = term;
this.fallbackMessage = fallbackMessage;
this.enableReload(true);
static <T> LocalString<T> immutable(String text) {
TranslationTerm term = TranslationTerm.createEmpty("static", text, StaticLocalString.DEFAULT_LOCALE);
return new StaticLocalString<>(term);
}

public LocalString<T> reload() {
TranslationTerm term = this.loader.getTranslationterm(key);
if (term == null) {
return this;
}
String getKey();

if (term.hasLocale(this.loader.getDefaultLocale())) {
this.term = term;
this.formatted.clear();
}
return this;
}
LocalString<T> reload();

public LocalString<T> enableReload(boolean enable) {
if (enable) {
this.loader.onStringSubscribe(this);
} else {
this.loader.onStringUnsubscribe(this);
}
return this;
}
LocalString<T> enableReload(boolean enable);

public LocalString<T> withArgument(String name, Object argument) {
default LocalString<T> withArgument(String name, Object argument) {
return this.withArgument(name, ctx -> String.valueOf(argument));
}

public LocalString<T> withArgument(String name, Function<TranslationContext<T>, String> mapper) {
this.arguments.put(name, mapper);
return this;
}
LocalString<T> withArgument(String name, Function<TranslationContext<T>, String> mapper);

public LocalString<T> clearArguments() {
this.arguments.clear();
return this;
}

protected Map<String, Function<TranslationContext<T>, String>> getArguments() {
return this.arguments;
}

public Collection<String> getArgumentNames() {
return Collections.unmodifiableCollection(this.arguments.keySet());
}

public TranslationContext<T> getTranslated(T object) {
TranslationContext.Factory<?> factory = contextFactories.get(object.getClass());
if (factory == null) {
factory = contextFactories.get(object.getClass().getSuperclass());
if (factory == null) {
throw new IllegalStateException("Unregistered factory for type " + object.getClass());
}
}
return ((TranslationContext.Factory<T>) factory).create(object, this);
}

public String getText(T object) {
return this.getTranslated(object).getText();
}

public String getFormatted(Locale locale) {
String formatted = this.formatted.get(locale);
if (formatted != null) {
return formatted;
}

String text = term.getText(locale);
if (text == null || text.trim().isEmpty()) {
text = term.getText(loader.getDefaultLocale());
}
LocalString<T> clearArguments();

this.formatted.put(locale, formatted = this.format(text));
return formatted;
}
String getFormatted();

private String format(String text) {
for (FormatterHandler formatter : formatters.values()) {
text = formatter.format(text);
}
return text;
}
String getFormatted(Locale locale);

public void uploadFallbackMessage() {
this.loader.addTermUpdate(TranslationTerm.createEmpty(key, this.fallbackMessage, loader.getDefaultLocale()));
}
String getText(T object);

@Override
public String toString() {
return "LocalString(key=" + this.key + ")";
}
void uploadFallbackMessage();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package eu.mizerak.alemiz.translationlib.common.string;

import eu.mizerak.alemiz.translationlib.common.structure.TranslationTerm;
import lombok.Getter;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;

public abstract class LocalStringBase<T> implements LocalString<T> {
private static final Map<StringFormatter, FormatterHandler> formatters = new ConcurrentHashMap<>();
private static final Map<Class<?>, TranslationContext.Factory<?>> contextFactories = new ConcurrentHashMap<>();

public static void registerFormatter(StringFormatter formatter) {
formatters.put(formatter, new FormatterHandler(formatter));
}

public static void unregisterFormatter(StringFormatter formatter) {
formatters.remove(formatter);
}

public static void registerContextFactory(Class<?> clazz, TranslationContext.Factory<?> factory) {
contextFactories.put(clazz, factory);
}

public static void unregisterContextFactory(Class<?> clazz) {
contextFactories.remove(clazz);
}


private final String key;

@Getter
private TranslationTerm term;

protected final Map<Locale, String> formatted = new ConcurrentHashMap<>();
protected final Map<String, Function<TranslationContext<T>, String>> arguments = new TreeMap<>();

protected LocalStringBase(String key, TranslationTerm term) {
this.key = key;
this.term = term;
}

@Override
public LocalStringBase<T> withArgument(String name, Object argument) {
return this.withArgument(name, ctx -> String.valueOf(argument));
}

@Override
public LocalStringBase<T> withArgument(String name, Function<TranslationContext<T>, String> mapper) {
this.arguments.put(name, mapper);
return this;
}

@Override
public LocalStringBase<T> clearArguments() {
this.arguments.clear();
return this;
}

public Collection<String> getArgumentNames() {
return Collections.unmodifiableCollection(this.arguments.keySet());
}

@Override
public String getText(T object) {
TranslationContext.Factory<?> factory = contextFactories.get(object.getClass());
if (factory == null) {
factory = contextFactories.get(object.getClass().getSuperclass());
if (factory == null) {
throw new IllegalStateException("Unregistered factory for type " + object.getClass());
}
}

TranslationContext<T> ctx = ((TranslationContext.Factory<T>) factory).create(object);

String formatted = this.getFormatted(ctx.getLocale());
if (!this.arguments.isEmpty()) {
for (Map.Entry<String, Function<TranslationContext<T>, String>> entry : this.arguments.entrySet()) {
formatted = formatted.replaceAll("\\{" + entry.getKey() + "\\}", entry.getValue().apply(ctx));
}
}
return formatted;
}

@Override
public String getFormatted(Locale locale) {
String formatted = this.formatted.get(locale);
if (formatted != null) {
return formatted;
}

String text = term.getText(locale);
if (text == null || text.trim().isEmpty()) {
text = term.getText(this.getDefaultLocale());
}

this.formatted.put(locale, formatted = this.format(text));
return formatted;
}

private String format(String text) {
for (FormatterHandler formatter : formatters.values()) {
text = formatter.format(text);
}
return text;
}

public abstract Locale getDefaultLocale();

@Override
public String getKey() {
return this.key;
}

@Override
public String toString() {
return "LocalString(key=" + this.key + ")";
}
}
Loading

0 comments on commit 35f4a21

Please sign in to comment.