Dave Jarvis' Repositories

git clone https://repo.autonoma.ca/repo/keenwrite.git

Reuse interpolator logic for resource bundle

AuthorDaveJarvis <email>
Date2021-12-05 23:17:07 GMT-0800
Commita8d62f2946aa105c2884239d9e82f56db28f50a7
Parente28c48f
Delta21 lines added, 115 lines removed, 94-line decrease
src/main/java/com/keenwrite/spelling/impl/SymSpellSpeller.java
while( (line = reader.readLine()) != null ) {
- final String[] sigils = line.split( "\\t" );
- map.put( sigils[ 0 ], parseLong( sigils[ 1 ] ) );
+ final var tokens = line.split( "\\t" );
+ map.put( tokens[ 0 ], parseLong( tokens[ 1 ] ) );
}
}
src/main/java/com/keenwrite/sigils/YamlSigilOperator.java
/**
- * Brackets definition keys with token delimiters.
+ * Responsible for bracketing definition keys with token delimiters.
*/
public final class YamlSigilOperator extends SigilOperator {
public YamlSigilOperator( final Sigils sigils ) {
super( sigils );
- }
-
- /**
- * Returns the given {@link String} verbatim because variables in YAML
- * documents and plain Markdown documents already have the appropriate
- * tokenizable syntax wrapped around the text.
- *
- * @param key Returned verbatim.
- */
- @Override
- public String apply( final String key ) {
- return key;
- }
-
- /**
- * Adds delimiters to the given key.
- *
- * @param key The key to adorn with start and stop definition tokens.
- * @return The given key bracketed by definition token symbols.
- */
- public String entoken( final String key ) {
- assert key != null;
- return getBegan() + key + getEnded();
}
src/main/java/com/keenwrite/Messages.java
import com.keenwrite.preferences.Key;
+import com.keenwrite.sigils.SigilOperator;
+import com.keenwrite.util.InterpolatingMap;
import java.text.MessageFormat;
-import java.util.Enumeration;
import java.util.ResourceBundle;
-import java.util.Stack;
import static com.keenwrite.constants.Constants.APP_BUNDLE_NAME;
public final class Messages {
- private static final ResourceBundle RESOURCE_BUNDLE =
- getBundle( APP_BUNDLE_NAME );
+ private static final SigilOperator OPERATOR = createBundleSigilOperator();
+ private static final InterpolatingMap MAP = new InterpolatingMap();
- private Messages() {
+ static {
+ // Obtains the application resource bundle using the default locale. The
+ // locale cannot be changed using the application, making interpolation of
+ // values viable as a one-time operation.
+ final var BUNDLE = getBundle( APP_BUNDLE_NAME );
+ BUNDLE.keySet().forEach( key -> MAP.put( key, BUNDLE.getString( key ) ) );
+ MAP.interpolate( OPERATOR );
}
-
- /**
- * Return the value of a resource bundle value after having resolved any
- * references to other bundle variables.
- *
- * @param props The bundle containing resolvable properties.
- * @param s The value for a key to resolve.
- * @return The value of the key with all references recursively dereferenced.
- */
- @SuppressWarnings( "SameParameterValue" )
- private static String resolve( final ResourceBundle props, final String s ) {
- final var len = s.length();
- final var stack = new Stack<StringBuilder>();
- var sb = new StringBuilder( 256 );
- var open = false;
-
- for( var i = 0; i < len; i++ ) {
- final var c = s.charAt( i );
-
- switch( c ) {
- case '$': {
- if( i + 1 < len && s.charAt( i + 1 ) == '{' ) {
- stack.push( sb );
-
- if( stack.size() > 20 ) {
- final var m = get( "Main.status.error.messages.recursion", s );
- throw new IllegalArgumentException( m );
- }
-
- sb = new StringBuilder( 256 );
- i++;
- open = true;
- }
-
- break;
- }
-
- case '}': {
- if( open ) {
- open = false;
- final var name = sb.toString();
-
- sb = stack.pop();
- sb.append( props.getString( name ) );
- break;
- }
- }
-
- default: {
- sb.append( c );
- break;
- }
- }
- }
-
- if( open ) {
- final var m = get( "Main.status.error.messages.syntax", s );
- throw new IllegalArgumentException( m );
- }
- return sb.toString();
+ private Messages() {
}
/**
* Returns the value for a key from the message bundle.
*
* @param key Retrieve the value for this key.
* @return The value for the key.
*/
public static String get( final String key ) {
- try {
- return resolve( RESOURCE_BUNDLE, RESOURCE_BUNDLE.getString( key ) );
- } catch( final Exception ignored ) {
- return key;
- }
+ return MAP.get( OPERATOR.entoken( key ) );
}
public static String get( final Key key ) {
return get( key.toString() );
- }
-
- public static String getLiteral( final String key ) {
- return RESOURCE_BUNDLE.getString( key );
- }
-
- public static String get( final String key, final boolean interpolate ) {
- return interpolate ? get( key ) : getLiteral( key );
}
/**
* Returns the value for a key from the message bundle with the arguments
- * replacing <code>{#}</code> place holders.
+ * replacing <code>{#}</code> placeholders.
*
* @param key Retrieve the value for this key.
- * @param args The values to substitute for place holders.
+ * @param args The values to substitute for placeholders.
* @return The value for the key.
*/
*/
public static boolean containsKey( final String key ) {
- return RESOURCE_BUNDLE.containsKey( key );
+ return MAP.containsKey( OPERATOR.entoken( key ) );
}
- /**
- * Returns all key names in the application's messages properties file.
- *
- * @return All key names in the {@link ResourceBundle} encapsulated by
- * this class.
- */
- public static Enumeration<String> getKeys() {
- return RESOURCE_BUNDLE.getKeys();
+ private static SigilOperator createBundleSigilOperator() {
+ return new SigilOperator( "${", "}" );
}
}