Issue #265: Created LabelService to support UI localization
This commit is contained in:
parent
4940a12d0d
commit
6acd149e5f
@ -0,0 +1,24 @@
|
|||||||
|
package org.owasp.webgoat.i18n;
|
||||||
|
|
||||||
|
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>ExposedReloadableResourceMessageBundleSource class.</p>
|
||||||
|
* Extends the reloadable message source with a way to get all messages
|
||||||
|
*
|
||||||
|
* @author zupzup
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ExposedReloadableResourceMessageBundleSource extends ReloadableResourceBundleMessageSource {
|
||||||
|
/**
|
||||||
|
* Gets all messages for presented Locale.
|
||||||
|
* @param locale user request's locale
|
||||||
|
* @return all messages
|
||||||
|
*/
|
||||||
|
public Properties getMessages(Locale locale) {
|
||||||
|
return getMergedProperties(locale).getProperties();
|
||||||
|
}
|
||||||
|
}
|
@ -9,9 +9,7 @@ import org.springframework.stereotype.Component;
|
|||||||
|
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.Arrays;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -52,8 +50,8 @@ public class LabelProvider {
|
|||||||
|
|
||||||
private static final List<Locale> SUPPORTED = Arrays.asList(Locale.GERMAN, Locale.FRENCH, Locale.ENGLISH,
|
private static final List<Locale> SUPPORTED = Arrays.asList(Locale.GERMAN, Locale.FRENCH, Locale.ENGLISH,
|
||||||
Locale.forLanguageTag("ru"));
|
Locale.forLanguageTag("ru"));
|
||||||
private final ReloadableResourceBundleMessageSource labels = new ReloadableResourceBundleMessageSource();
|
private final ExposedReloadableResourceMessageBundleSource labels = new ExposedReloadableResourceMessageBundleSource();
|
||||||
private static final ReloadableResourceBundleMessageSource pluginLabels = new ReloadableResourceBundleMessageSource();
|
private static final ExposedReloadableResourceMessageBundleSource pluginLabels = new ExposedReloadableResourceMessageBundleSource();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Constructor for LabelProvider.</p>
|
* <p>Constructor for LabelProvider.</p>
|
||||||
@ -104,7 +102,27 @@ public class LabelProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Locale useLocaleOrFallbackToEnglish(Locale locale) {
|
private Locale useLocaleOrFallbackToEnglish(Locale locale) {
|
||||||
return SUPPORTED.contains(locale) ? Locale.ENGLISH : locale;
|
return SUPPORTED.contains(locale) ? locale : Locale.ENGLISH;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>getLabels.</p>
|
||||||
|
* Returns a merged map of all the labels for a specified language or the
|
||||||
|
* default language, if the given language is not supported
|
||||||
|
*
|
||||||
|
* @param locale The Locale to get all the labels for
|
||||||
|
* @return A Map of all properties with their values
|
||||||
|
*/
|
||||||
|
public Map<String, String> getLabels(Locale locale) {
|
||||||
|
Properties messages = labels.getMessages(locale);
|
||||||
|
messages.putAll(pluginLabels.getMessages(useLocaleOrFallbackToEnglish(locale)));
|
||||||
|
Map<String,String> labelsMap = new HashMap<>();
|
||||||
|
for (Map.Entry<Object, Object> entry : messages.entrySet()) {
|
||||||
|
if (entry.getKey() != null && entry.getValue() != null) {
|
||||||
|
labelsMap.put(entry.getKey().toString(), entry.getValue().toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return labelsMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,63 @@
|
|||||||
|
package org.owasp.webgoat.service;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.i18n.LabelProvider;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>LabelService class.</p>
|
||||||
|
*
|
||||||
|
* @author zupzup
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
public class LabelService {
|
||||||
|
|
||||||
|
private static final String URL_LABELS_MVC = "/service/labels.mvc";
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(LabelService.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private LabelProvider labelProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches labels for given language
|
||||||
|
* If no language is provided, the language is determined from the request headers
|
||||||
|
* Otherwise, fall back to default language
|
||||||
|
*
|
||||||
|
* @param lang the language to fetch labels for (optional)
|
||||||
|
* @return a map of labels
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
@RequestMapping(path = URL_LABELS_MVC, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||||
|
public @ResponseBody
|
||||||
|
ResponseEntity<Map<String, String>> fetchLabels(@RequestParam(value = "lang", required = false) String lang, HttpServletRequest request) throws Exception {
|
||||||
|
Locale locale;
|
||||||
|
if (StringUtils.isEmpty(lang)) {
|
||||||
|
logger.debug("No language provided, determining from request headers");
|
||||||
|
locale = request.getLocale();
|
||||||
|
if (locale != null) {
|
||||||
|
logger.debug("Locale set to {}", locale);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
locale = Locale.forLanguageTag(lang);
|
||||||
|
logger.debug("Language provided: {} leads to Locale: {}", lang, locale);
|
||||||
|
}
|
||||||
|
return new ResponseEntity<>(labelProvider.getLabels(locale), HttpStatus.OK);
|
||||||
|
}
|
||||||
|
}
|
@ -17,4 +17,18 @@ public class LabelProviderTest {
|
|||||||
"Congratulations. You have successfully completed this lesson."));
|
"Congratulations. You have successfully completed this lesson."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldFallBackToEnglishIfLanguageNotSupported() {
|
||||||
|
LabelProvider labelProvider = new LabelProvider();
|
||||||
|
assertThat(labelProvider.get(Locale.CHINESE, "LessonCompleted"), CoreMatchers.equalTo(
|
||||||
|
"Congratulations. You have successfully completed this lesson."));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldUseProvidedLanguageIfSupported() {
|
||||||
|
LabelProvider labelProvider = new LabelProvider();
|
||||||
|
assertThat(labelProvider.get(Locale.GERMAN, "RestartLesson"), CoreMatchers.equalTo(
|
||||||
|
"Lektion neu beginnen"));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user