-
Notifications
You must be signed in to change notification settings - Fork 49
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added an i1n framework to komodo-common. Localized the strings that n…
…eeded localization in all projects except komodo-shell.
- Loading branch information
1 parent
317bc6d
commit 3874ff9
Showing
22 changed files
with
510 additions
and
3 deletions.
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
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
36 changes: 36 additions & 0 deletions
36
komodo-common/src/main/java/org/komodo/common/CommonI18n.java
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,36 @@ | ||
package org.komodo.common; | ||
|
||
import org.komodo.common.i18n.I18n; | ||
|
||
/* | ||
* JBoss, Home of Professional Open Source. | ||
* | ||
* See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. | ||
* | ||
* See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. | ||
*/ | ||
|
||
/** | ||
* Localized messages of the komodo-common module. | ||
*/ | ||
@SuppressWarnings( {"javadoc"} ) | ||
public class CommonI18n extends I18n { | ||
|
||
public static String missingI18Field; | ||
public static String missingPropertiesKey; | ||
public static String problemAccessingI18Field; | ||
public static String problemLoadingI18nClass; | ||
public static String problemLoadingI18nProperties; | ||
|
||
static { | ||
final CommonI18n i18n = new CommonI18n(); | ||
i18n.initialize(); | ||
} | ||
|
||
/** | ||
* Don't allow public construction. | ||
*/ | ||
private CommonI18n() { | ||
// nothing to do | ||
} | ||
} |
165 changes: 165 additions & 0 deletions
165
komodo-common/src/main/java/org/komodo/common/i18n/I18n.java
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,165 @@ | ||
/* | ||
* JBoss, Home of Professional Open Source. | ||
* | ||
* See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. | ||
* | ||
* See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. | ||
*/ | ||
package org.komodo.common.i18n; | ||
|
||
import java.io.InputStream; | ||
import java.lang.reflect.Field; | ||
import java.lang.reflect.Modifier; | ||
import java.net.URL; | ||
import java.util.ArrayList; | ||
import java.util.Collection; | ||
import java.util.Formatter; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.Properties; | ||
import org.komodo.common.CommonI18n; | ||
import org.komodo.common.util.CollectionUtil; | ||
import org.komodo.common.util.Precondition; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
/** | ||
* A class that can be subclassed and used to internationalize property files. All public, static, and non-final strings | ||
* in the subclass will be set to the default locale's value in the associated property file value. The placeholders used in | ||
* the messages are those that are used by {@link Formatter}. | ||
*/ | ||
public abstract class I18n { | ||
|
||
class I18nProperties extends Properties { | ||
|
||
private static final long serialVersionUID = 297271848138379264L; | ||
|
||
private final Class<I18n> clazz; | ||
private final Collection<String> errors; | ||
private final Map<String, Field> fields; | ||
|
||
I18nProperties(final Map<String, Field> fields, | ||
final Class<I18n> clazz, | ||
final Collection<String> errors) { | ||
this.clazz = clazz; | ||
this.fields = fields; | ||
this.errors = errors; | ||
} | ||
|
||
/** | ||
* {@inheritDoc} | ||
* | ||
* @see java.util.Hashtable#put(java.lang.Object, java.lang.Object) | ||
*/ | ||
@Override | ||
public synchronized Object put(final Object key, | ||
final Object value) { | ||
if (this.fields.containsKey(key)) { | ||
try { | ||
final Field field = this.clazz.getDeclaredField((String)key); | ||
field.set(null, value); | ||
this.fields.remove(key); | ||
} catch (final Exception e) { | ||
this.errors.add(I18n.bind(CommonI18n.problemAccessingI18Field, key, this.clazz.getName())); | ||
} | ||
} else { | ||
this.errors.add(I18n.bind(CommonI18n.missingI18Field, key, this.clazz.getName())); | ||
} | ||
|
||
return super.put(key, value); | ||
} | ||
|
||
} | ||
|
||
private final Logger logger = LoggerFactory.getLogger(getClass()); | ||
|
||
/** | ||
* @param pattern the message pattern (cannot be <code>null</code> or empty) | ||
* @param args the arguments being used to replace placeholders in the message (can be <code>null</code> or empty) | ||
* @return the localized message (never <code>null</code>) | ||
*/ | ||
public static String bind(final String pattern, | ||
final Object... args) { | ||
Precondition.notEmpty(pattern, "pattern"); //$NON-NLS-1$ | ||
return String.format(pattern, args); | ||
} | ||
|
||
/** | ||
* Should be called in a <code>static</code> block to load the properties file and assign values to the class string fields. | ||
* | ||
* @throws IllegalStateException if there is a problem reading the I8n class file or properties file | ||
*/ | ||
protected void initialize() { | ||
final Map<String, Field> fields = new HashMap<String, Field>(); | ||
|
||
// collect all public, static, non-final, string fields | ||
try { | ||
for (final Field field : getClass().getDeclaredFields()) { | ||
final int modifiers = field.getModifiers(); | ||
|
||
if ((field.getType() == String.class) && ((modifiers & Modifier.PUBLIC) == Modifier.PUBLIC) | ||
&& ((modifiers & Modifier.STATIC) == Modifier.STATIC) && ((modifiers & Modifier.FINAL) != Modifier.FINAL)) { | ||
fields.put(field.getName(), field); | ||
} | ||
} | ||
} catch (final Exception e) { | ||
throw new IllegalStateException(I18n.bind(CommonI18n.problemLoadingI18nClass, getClass().getName()), e); | ||
} | ||
|
||
// return if nothing to do | ||
if (CollectionUtil.isEmpty(fields)) { | ||
return; | ||
} | ||
|
||
// load properties file | ||
InputStream stream = null; | ||
IllegalStateException problem = null; | ||
|
||
try { | ||
final Class thisClass = getClass(); | ||
final String bundleName = thisClass.getName().replaceAll("\\.", "/").concat(".properties"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ | ||
final URL url = thisClass.getClassLoader().getResource(bundleName); | ||
stream = url.openStream(); | ||
|
||
final Collection<String> errors = new ArrayList<String>(); | ||
final Properties props = new I18nProperties(fields, thisClass, errors); | ||
props.load(stream); | ||
|
||
// log errors for any properties keys that don't have fields | ||
for (String error : errors) { | ||
if (problem == null) { | ||
problem = new IllegalStateException(error); | ||
} | ||
|
||
this.logger.error(error); | ||
} | ||
|
||
// log errors for any fields that don't have properties | ||
for (final String fieldName : fields.keySet()) { | ||
final String error = I18n.bind(CommonI18n.missingPropertiesKey, fieldName, getClass().getName()); | ||
|
||
if (problem == null) { | ||
problem = new IllegalStateException(error); | ||
} | ||
|
||
this.logger.error(error); | ||
} | ||
} catch (final Exception e) { | ||
throw new IllegalStateException(I18n.bind(CommonI18n.problemLoadingI18nProperties, getClass().getName()), e); | ||
} finally { | ||
if (stream != null) { | ||
try { | ||
stream.close(); | ||
} catch (final Exception e) { | ||
} finally { | ||
stream = null; | ||
} | ||
} | ||
|
||
if (problem != null) { | ||
throw problem; | ||
} | ||
} | ||
} | ||
|
||
} |
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
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,14 @@ | ||
# Direct log messages to stdout | ||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender | ||
log4j.appender.stdout.Target=System.out | ||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout | ||
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %m%n | ||
|
||
# Root logger option | ||
log4j.rootLogger=INFO, stdout | ||
|
||
# Set up the default logging to be INFO level, then override specific units | ||
log4j.logger.org.komodo.common=INFO | ||
|
||
# Uncomment to turn debug logging on | ||
#log4j.logger.org.komodo.common.I18n=DEBUG |
14 changes: 14 additions & 0 deletions
14
komodo-common/src/main/resources/org/komodo/common/CommonI18n.properties
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,14 @@ | ||
# 1 = name of key, 2 = class name of I18n subclass | ||
missingI18Field = The properties key '%s' does not have a corresponding field in I18n '%s' | ||
|
||
# 1 = I18n field name, 2 = class name of I18n subclass | ||
missingPropertiesKey = The field '%s' in I18n '%s' does not have a corresponding entry in the properties file | ||
|
||
# 1 = I18n field name, 2 = class name of I18n subclass | ||
problemAccessingI18Field = There was a problem accessing field '%s' in I18n '%s' | ||
|
||
# 1 = class name of I18n subclass | ||
problemLoadingI18nClass = There was a problem loading I18n '%s' field values | ||
|
||
# 1 = class name of I18n subclass | ||
problemLoadingI18nProperties = There was a problem loading properties file for I18n '%s' |
42 changes: 42 additions & 0 deletions
42
komodo-common/src/test/java/org/komodo/common/GoodI18nTest.java
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,42 @@ | ||
/* | ||
* JBoss, Home of Professional Open Source. | ||
* | ||
* See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. | ||
* | ||
* See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. | ||
*/ | ||
package org.komodo.common; | ||
|
||
import static org.hamcrest.core.Is.is; | ||
import static org.junit.Assert.assertThat; | ||
import org.junit.BeforeClass; | ||
import org.junit.Test; | ||
import org.komodo.common.i18n.I18n; | ||
|
||
/** | ||
* A test class for {@link I18n}. | ||
*/ | ||
@SuppressWarnings( {"javadoc", "nls"} ) | ||
public class GoodI18nTest extends I18n { | ||
|
||
public static String field; | ||
public static String patternOneArg; | ||
|
||
@BeforeClass | ||
public static void setup() { | ||
final GoodI18nTest i18n = new GoodI18nTest(); | ||
i18n.initialize(); | ||
} | ||
|
||
@Test | ||
public void shouldSetFieldWithNoArg() { | ||
assertThat(GoodI18nTest.field, is("test field")); | ||
} | ||
|
||
@Test | ||
public void shouldSetFieldWithOneArg() { | ||
final String arg = "argOne"; | ||
assertThat(I18n.bind(GoodI18nTest.patternOneArg, arg), is("test pattern " + arg)); | ||
} | ||
|
||
} |
27 changes: 27 additions & 0 deletions
27
komodo-common/src/test/java/org/komodo/common/MissingFieldI18nTest.java
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,27 @@ | ||
/* | ||
* JBoss, Home of Professional Open Source. | ||
* | ||
* See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. | ||
* | ||
* See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. | ||
*/ | ||
package org.komodo.common; | ||
|
||
import org.junit.Test; | ||
import org.komodo.common.i18n.I18n; | ||
|
||
/** | ||
* A test class for {@link I18n}. | ||
*/ | ||
@SuppressWarnings( {"javadoc"} ) | ||
public class MissingFieldI18nTest extends I18n { | ||
|
||
public static String field; | ||
|
||
@Test( expected = IllegalStateException.class ) | ||
public void shouldNotInitialize() { | ||
final MissingFieldI18nTest i18n = new MissingFieldI18nTest(); | ||
i18n.initialize(); | ||
} | ||
|
||
} |
28 changes: 28 additions & 0 deletions
28
komodo-common/src/test/java/org/komodo/common/MissingKeyI18nTest.java
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,28 @@ | ||
/* | ||
* JBoss, Home of Professional Open Source. | ||
* | ||
* See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. | ||
* | ||
* See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. | ||
*/ | ||
package org.komodo.common; | ||
|
||
import org.junit.Test; | ||
import org.komodo.common.i18n.I18n; | ||
|
||
/** | ||
* A test class for {@link I18n}. | ||
*/ | ||
@SuppressWarnings( {"javadoc"} ) | ||
public class MissingKeyI18nTest extends I18n { | ||
|
||
public static String field; | ||
public static String missingKeyField; | ||
|
||
@Test( expected = IllegalStateException.class ) | ||
public void shouldNotInitialize() { | ||
final MissingKeyI18nTest i18n = new MissingKeyI18nTest(); | ||
i18n.initialize(); | ||
} | ||
|
||
} |
Oops, something went wrong.