Source code: javax/ide/extension/I18NStringVisitor.java
1 package javax.ide.extension;
2
3 import java.util.Locale;
4 import java.util.MissingResourceException;
5 import java.util.ResourceBundle;
6
7 import java.util.logging.Level;
8 import javax.ide.extension.spi.ExtensionVisitor;
9
10 /**
11 * An element visitor that processes xml elements of type i18n_string. If
12 * the element has an rskey attribute and an ancestor extension element defined
13 * a bundle using the rsbundle attribute, this implementation will use
14 * ResourceBundle.getBundle() to load a string resource from the bundle class.
15 * If no rskey attribute is present, the text of the element will be used
16 * instead. In either case, {@link #string( ElementContext, String )} is called
17 * with the resulting string.<p>
18 *
19 * An error is logged if the rskey attribute is present on the element but no
20 * rsbundle was defined in an ancestor extension element.
21 */
22 public abstract class I18NStringVisitor extends ElementVisitor
23 {
24 protected static final String KEY_RSKEY = "rskey";
25
26 public void start( ElementStartContext start )
27 {
28 String rskey = start.getAttributeValue( "rskey" );
29 if ( rskey != null && ( rskey = rskey.trim()).length() == 0 )
30 {
31 // Must put null in the map so that we don't inherit rskey from parent
32 // element.
33 rskey = null;
34 }
35
36 // Check that we have an rsbundle. Otherwise, the use of rskey is flagged
37 // as a warning.
38 String rsBundleClass = (String) start.getScopeData().get(
39 ExtensionHook.KEY_RSBUNDLE_CLASS );
40 if ( rskey != null && rsBundleClass == null )
41 {
42 log( start, Level.WARNING,
43 "'rskey' used without 'rsbundle' on extension element."
44 );
45 rskey = null;
46 }
47 start.getScopeData().put( KEY_RSKEY, rskey );
48 }
49
50 public void end( ElementEndContext end )
51 {
52 String rskey = (String) end.getScopeData().get( KEY_RSKEY );
53 String value = null;
54 if ( rskey != null )
55 {
56 String bundleClass = (String) end.getScopeData().get(
57 ExtensionHook.KEY_RSBUNDLE_CLASS );
58 try
59 {
60 value = lookupResource( end, bundleClass, rskey );
61 }
62 catch ( MissingResourceException mre )
63 {
64 log( end, Level.WARNING,
65 "Resource key '"+rskey+"' not found in bundle '"+bundleClass+"'."
66 );
67 // Fall back to the text node, if any.
68 value = null;
69 }
70 }
71
72 if ( value == null )
73 {
74 value = end.getText();
75 if ( value == null )
76 {
77 value = "";
78 }
79 }
80
81 string( end, value.trim() );
82 }
83
84 private String lookupResource( ElementContext context,
85 String bundleClass, String key )
86 {
87 ClassLoader cl = (ClassLoader) context.getScopeData().get(
88 ExtensionVisitor.KEY_CLASSLOADER );
89 if ( cl == null )
90 {
91 cl = Thread.currentThread().getContextClassLoader();
92 }
93
94 ResourceBundle bundle = ResourceBundle.getBundle( bundleClass,
95 Locale.getDefault(), cl );
96 return bundle.getString( key );
97 }
98
99 /**
100 * Called when the visitor has processed a translatable string.
101 *
102 * @param context the context for parsing.
103 * @param string the (possibly translated) string.
104 */
105 protected abstract void string( ElementContext context, String string );
106 }