Skip to content

Commit 8cf50e6

Browse files
committed
Merge branch 'release/0.8' into develop
2 parents e326fa1 + 4711034 commit 8cf50e6

File tree

9 files changed

+343
-0
lines changed

9 files changed

+343
-0
lines changed
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package org.fugerit.java.core.util.i18n;
2+
3+
import java.util.HashMap;
4+
import java.util.Locale;
5+
import java.util.Map;
6+
import java.util.MissingResourceException;
7+
import java.util.ResourceBundle;
8+
9+
import org.fugerit.java.core.lang.helpers.StringUtils;
10+
import org.slf4j.Logger;
11+
import org.slf4j.LoggerFactory;
12+
13+
public class BundleMapI18N extends HelperI18N {
14+
15+
private static final Logger logger = LoggerFactory.getLogger( BundleMapI18N.class );
16+
17+
private static void addBundle( Map<String, ResourceBundle> bundleMap, String baseName, String lang ) {
18+
Locale langTag = Locale.forLanguageTag( lang );
19+
ResourceBundle bundle = ResourceBundle.getBundle( baseName, langTag, new XMLResourceBundleControl() );
20+
logger.info( "adding bundle, lang : {} -> {}", lang, langTag );
21+
bundleMap.put( lang , bundle );
22+
}
23+
24+
private static void createBundleMap( Map<String, ResourceBundle> bundleMap, String baseName, String defaultLanguge, String... altLocale ) {
25+
addBundle(bundleMap, baseName, defaultLanguge);
26+
for ( int k=0; k<altLocale.length; k++ ) {
27+
addBundle(bundleMap, baseName, altLocale[k]);
28+
}
29+
}
30+
31+
public static HelperI18N newHelperI18N( String baseName, String defaultLanguge, String... altLocale ) {
32+
HelperI18N helper = new BundleMapI18N(baseName, defaultLanguge, altLocale);
33+
return helper;
34+
}
35+
36+
public BundleMapI18N(String baseName, String defaultLanguge, String... altLocale) {
37+
super(baseName, defaultLanguge, altLocale);
38+
this.bundleMap = new HashMap<String, ResourceBundle>();
39+
createBundleMap(this.bundleMap, baseName, defaultLanguge, altLocale);
40+
}
41+
42+
public Map<String, ResourceBundle> getBundleMap() {
43+
return bundleMap;
44+
}
45+
46+
public ResourceBundle findBundle( String lang ) {
47+
ResourceBundle bundle = null;
48+
if ( StringUtils.isNotEmpty( lang ) ) {
49+
bundle = this.getBundleMap().get( lang );
50+
} else {
51+
bundle = this.getBundleMap().get( this.getDefaultLanguage() );
52+
}
53+
return bundle;
54+
}
55+
56+
57+
private Map<String, ResourceBundle> bundleMap;
58+
59+
@Override
60+
public String resolveString(String lang, String key) {
61+
String message = null;
62+
try {
63+
ResourceBundle bundle = this.findBundle( lang );
64+
if ( bundle != null ) {
65+
message = bundle.getString( key );
66+
}
67+
} catch (MissingResourceException mre) {
68+
logger.warn( "Property not found : "+key+" (lang:"+lang+")" );
69+
}
70+
return message;
71+
}
72+
73+
74+
75+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package org.fugerit.java.core.util.i18n;
2+
3+
import java.text.MessageFormat;
4+
import java.util.Arrays;
5+
import java.util.List;
6+
7+
public abstract class HelperI18N {
8+
9+
protected HelperI18N( String baseName, String defaultLanguge, String... altLocale ) {
10+
this.defaultLanguage = defaultLanguge;
11+
this.altLocale = altLocale;
12+
if ( this.altLocale == null ) {
13+
this.altLocale = new String[0];
14+
}
15+
}
16+
17+
private String defaultLanguage;
18+
19+
private String[] altLocale;
20+
21+
public String getDefaultLanguage() {
22+
return defaultLanguage;
23+
}
24+
25+
public List<String> getAltLocale() {
26+
return Arrays.asList( this.altLocale );
27+
}
28+
29+
public abstract String resolveString( String lang, String key );
30+
31+
public String getString( String lang, String key, Object... params ) {
32+
String message = this.resolveString(lang, key);
33+
if ( message != null && params != null && params.length > 0 ) {
34+
Object[] realParams = new Object[ params.length ];
35+
for ( int k=0; k<params.length; k++ ) {
36+
Object current = params[k];
37+
if ( current instanceof ParamI18N ) {
38+
current = this.resolveString( lang, ((ParamI18N)current).getKey() );
39+
}
40+
realParams[k] = current;
41+
}
42+
message = MessageFormat.format( message, realParams );
43+
}
44+
return message;
45+
}
46+
47+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package org.fugerit.java.core.util.i18n;
2+
3+
public class I18NException extends Exception {
4+
5+
/**
6+
*
7+
*/
8+
private static final long serialVersionUID = 8846663679327813642L;
9+
10+
public I18NException() {
11+
super();
12+
}
13+
14+
public I18NException(String message, Throwable cause) {
15+
super(message, cause);
16+
}
17+
18+
public I18NException(String message) {
19+
super(message);
20+
}
21+
22+
public I18NException(Throwable cause) {
23+
super(cause);
24+
}
25+
26+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package org.fugerit.java.core.util.i18n;
2+
3+
public class ParamI18N {
4+
5+
private ParamI18N( String key ) {
6+
this.key = key;
7+
}
8+
9+
private String key;
10+
11+
public String getKey() {
12+
return key;
13+
}
14+
15+
public static ParamI18N newParamI18N( String key ) {
16+
return new ParamI18N( key );
17+
}
18+
19+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package org.fugerit.java.core.util.i18n;
2+
3+
import java.io.BufferedInputStream;
4+
import java.io.IOException;
5+
import java.io.InputStream;
6+
import java.net.URL;
7+
import java.net.URLConnection;
8+
import java.util.Arrays;
9+
import java.util.Enumeration;
10+
import java.util.List;
11+
import java.util.Locale;
12+
import java.util.Properties;
13+
import java.util.ResourceBundle;
14+
15+
public class XMLResourceBundleControl extends ResourceBundle.Control {
16+
17+
@Override
18+
public List<String> getFormats(String baseName) {
19+
if (baseName == null) {
20+
throw new IllegalArgumentException( "baseName must be provided" );
21+
}
22+
return Arrays.asList("xml");
23+
}
24+
25+
@Override
26+
public ResourceBundle newBundle(String baseName, Locale locale,
27+
String format,
28+
ClassLoader loader,
29+
boolean reload)
30+
throws IllegalAccessException,
31+
InstantiationException, IOException {
32+
if (baseName == null || locale == null
33+
|| format == null || loader == null) {
34+
throw new IllegalArgumentException( "incomplete configuration (baseName, locale, format and loader must be provided)" );
35+
}
36+
ResourceBundle bundle = null;
37+
if (format.equals("xml")) {
38+
String bundleName = toBundleName(baseName, locale);
39+
String resourceName = toResourceName(bundleName, format);
40+
URL url = loader.getResource(resourceName);
41+
if (url != null) {
42+
URLConnection connection = url.openConnection();
43+
if (connection != null) {
44+
if (reload) {
45+
// disable caches if reloading
46+
connection.setUseCaches(false);
47+
}
48+
try (InputStream stream = connection.getInputStream()) {
49+
if (stream != null) {
50+
BufferedInputStream bis =
51+
new BufferedInputStream(stream);
52+
bundle = new XMLResourceBundle(bis);
53+
}
54+
}
55+
}
56+
}
57+
}
58+
return bundle;
59+
}
60+
61+
private static class XMLResourceBundle extends ResourceBundle {
62+
private Properties props;
63+
64+
XMLResourceBundle(InputStream stream) throws IOException {
65+
props = new Properties();
66+
props.loadFromXML(stream);
67+
}
68+
69+
protected Object handleGetObject(String key) {
70+
if (key == null) {
71+
throw new IllegalArgumentException( "key must be provided" );
72+
}
73+
return props.get(key);
74+
}
75+
76+
@SuppressWarnings("unchecked")
77+
public Enumeration<String> getKeys() {
78+
return (Enumeration<String>) props.propertyNames();
79+
}
80+
}
81+
82+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package test.org.fugerit.java.core.util.i18n;
2+
3+
import org.fugerit.java.core.util.i18n.BundleMapI18N;
4+
import org.fugerit.java.core.util.i18n.HelperI18N;
5+
import org.fugerit.java.core.util.i18n.ParamI18N;
6+
import org.junit.Assert;
7+
import org.junit.Before;
8+
import org.junit.Test;
9+
import org.slf4j.Logger;
10+
import org.slf4j.LoggerFactory;
11+
12+
public class TestHelperI18N {
13+
14+
public final static String LANG_EN = "en";
15+
16+
public final static String LANG_IT = "it";
17+
18+
public final static String LANG_DEF = LANG_EN;
19+
20+
public final static String LANG_ALT[] = { LANG_IT };
21+
22+
private final static Logger logger = LoggerFactory.getLogger( TestHelperI18N.class );
23+
24+
private static final String CONF_PATH = "core.util.i18n.test";
25+
26+
private HelperI18N helper;
27+
28+
private void testHelper( String expectedValue, String lang, String key, Object... params ) {
29+
String value = this.helper.getString( lang , key, params );
30+
logger.info( "key:{} , lang:{} -> {}", lang, key, value );
31+
Assert.assertEquals( "Value different for key : "+key+", lang : "+lang , expectedValue, value );
32+
}
33+
34+
@Before
35+
public void init() {
36+
this.helper = BundleMapI18N.newHelperI18N( CONF_PATH, LANG_DEF, LANG_ALT );
37+
}
38+
39+
@Test
40+
public void testSimpleProperty1() {
41+
String key = "test.prop.1"; // test.prop.1 is available for both languages
42+
this.testHelper( "Test property 1", LANG_DEF, key );
43+
this.testHelper( "Proprietà test 1", LANG_ALT[0], key );
44+
}
45+
46+
@Test
47+
public void testSimpleProperty2() {
48+
String key = "test.prop.2"; // test.prop.2 is available only for default language
49+
this.testHelper( "Test property 2", LANG_DEF, key );
50+
this.testHelper( "Test property 2", LANG_ALT[0], key );
51+
}
52+
53+
@Test
54+
public void testSimpleProperty3() {
55+
String key = "test.prop.3"; // test.prop.3 is available only for default language
56+
this.testHelper( null, LANG_DEF, key );
57+
this.testHelper( "Proprietà test 3", LANG_ALT[0], key );
58+
}
59+
60+
@Test
61+
public void testComplexProperty1() {
62+
String key = "test.complex.prop.1"; // contains a integer param and a i18n param
63+
String keyParam = "test.param.1"; // the key for the i18n param
64+
this.testHelper( "Complex property 1 -> simple parameter : 3 and i18n parameter : (ParamI18N value)",
65+
LANG_DEF, key, new Integer( 3 ), ParamI18N.newParamI18N( keyParam ) );
66+
this.testHelper( "Proprietà complessa test 1 -> parametro semplice : 3 e parametro i18n : (valore ParamI18N)",
67+
LANG_ALT[0], key, new Integer( 3 ), ParamI18N.newParamI18N( keyParam ) );
68+
}
69+
70+
71+
72+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
3+
<properties>
4+
<entry key="test.prop.1">Test property 1</entry>
5+
<entry key="test.prop.2">Test property 2</entry>
6+
<entry key="test.complex.prop.1">Complex property 1 -> simple parameter : {0} and i18n parameter : {1}</entry>
7+
<entry key="test.param.1">(ParamI18N value)</entry>
8+
</properties>
9+
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
3+
<properties>
4+
</properties>
5+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
3+
<properties>
4+
<entry key="test.prop.1">Proprietà test 1</entry>
5+
<entry key="test.prop.3">Proprietà test 3</entry>
6+
<entry key="test.complex.prop.1">Proprietà complessa test 1 -> parametro semplice : {0} e parametro i18n : {1}</entry>
7+
<entry key="test.param.1">(valore ParamI18N)</entry>
8+
</properties>

0 commit comments

Comments
 (0)