platform-core-home/documents/3.1/message_bundles.html

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (view) (download) (as text)

1 : dj 1.1 <!doctype html public "-//w3c//dtd html 4.0 transitional//en">
2 :     <html>
3 :     <head>
4 :     <title>Eclipse Platform/Core</title>
5 :     <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6 :     <link rel="stylesheet" href="http://dev.eclipse.org/default_style.css" type="text/css">
7 :     <STYLE TYPE="text/css">
8 :     <!--
9 :     CODE { font-size: 80% }
10 :     -->
11 :     </STYLE>
12 :     </head>
13 :     <body>
14 :     <center>
15 :     <font class=indextop>core</font><br>
16 :     <font class=indexsub>the foundation of the platform</font><p></p>
17 :     <a href="../../main.html">[home]</a>
18 :     <a href="../../documents.html">[documents]</a>
19 :     <a href="../../downloads.html">[downloads]</a>
20 :     <a href="../../resources.html">[resources]</a>
21 :     <a href="../../planning.html">[planning]</a>
22 :     <a href="../../testing.html">[testing]</a>
23 :     </center>
24 :     <br>
25 :     <table BORDER=0 CELLPADDING=2 WIDTH="100%" >
26 :     <tr>
27 :     <td ALIGN=LEFT VALIGN=TOP COLSPAN="2" BGCOLOR="#0080C0"><b><font face="Arial,Helvetica" color="#FFFFFF">Message Bundles</font></b></td>
28 :     </tr>
29 :     <tr>
30 :     <td ALIGN=RIGHT VALIGN=TOP WIDTH="2%"><img SRC="../../images/Adarrow.gif" BORDER=0 height=16 width=16></td>
31 :    
32 :     <td WIDTH="98%"><b>Description</b> <p>This is a description of the new message
33 :     bundle format story for Eclipse.</p>
34 :     <p>Summary of the new format:</p>
35 :     <ul>
36 :     <li>messages.properties - same as before except keys need to be valid
37 :     Java identifier names (replace "." with "_", etc)
38 :     <li>Java file has a static String field for each message
39 :     <li>On startup, we set the values of the fields to be the strings from
40 :     the messages.properties files and then discard the properties file from
41 :     memory.
42 :     </ul> <p>When creating a new message:</p>
43 :     <ul>
44 :     <li>create a field in your Messages.java file</li>
45 :     <li>create a key/value pair in your messages.properties file</li>
46 :     <li>the key MUST be the same as the field name</li>
47 :     <li>in your code, just use the field reference rather than a lookup (e.g.
48 :     Messages.my_key)</li>
49 :     </ul>
50 :     <p>&nbsp;</p></td>
51 :     </tr>
52 :     <tr>
53 :     <td ALIGN=LEFT VALIGN=TOP COLSPAN="2" BGCOLOR="#0080C0"><b><font face="Arial,Helvetica" color="#FFFFFF">Performance</font></b></td>
54 :     </tr>
55 :     <tr>
56 :     <td ALIGN=RIGHT VALIGN=TOP WIDTH="2%"><img SRC="../../images/Adarrow.gif" BORDER=0 height=16 width=16></td>
57 :    
58 :     <td WIDTH="98%"><b>Time</b>
59 :     <p>The code is faster since accessing the messages is just a field access
60 :     rather than a lookup in the resource bundle. </p>
61 :     <p>Our performance results indicate the time to load and initialize bundle
62 :     are VM dependant but are 5% to 46% faster using the new mechanism.</p>
63 :     <p>&nbsp;</p>
64 :     </td>
65 :     </tr>
66 :     <tr>
67 :     <td ALIGN=RIGHT VALIGN=TOP WIDTH="2%"><img SRC="../../images/Adarrow.gif" BORDER=0 height=16 width=16></td>
68 :    
69 :     <td WIDTH="98%"><b>Memory Footprint</b>
70 :     <p>With the new mechanism, the rough space savings is 88 + 5N per message
71 :     where N is the length of the keys. </p>
72 :     <p>We have calculated in the best-case scenerio for the Eclipse SDK if every
73 :     key in every properties file was referenced, then the savings would be
74 :     roughly 4.5M. (based on the January 11, 2005 integration build)</p>
75 :     <p>&nbsp;</p>
76 :     </td>
77 :     </tr>
78 :     <tr>
79 :     <td ALIGN=RIGHT VALIGN=TOP WIDTH="2%"><img SRC="../../images/Adarrow.gif" BORDER=0 height=16 width=16></td>
80 :    
81 :     <td WIDTH="98%"><b>Other benefits</b> <ul>
82 :     <li>Easily catch missing keys - Message lookups are now field accesses
83 :     so you cannot reference a key that doesn't exist or you will get a compile
84 :     error. </li>
85 :     <li>Easily find typos in code when referencing keys - Each key is represented
86 :     by a field in the class so if the referencing code makes a spelling
87 :     error, then you will get a compile error.</li>
88 :     <li>Find unused keys - During the development cycle code is deleted, moved
89 :     and messages are changed. As a result there are keys in the messages.properties
90 :     file which are never referenced.These can easily be found now since
91 :     you can just do a search for references to the field. If there are no
92 :     references, then delete the field from the class and the key/value pair
93 :     from the file.</li>
94 :     </ul>
95 :     <p>&nbsp;</p></td>
96 :     </tr>
97 :     <tr>
98 :     <td ALIGN=RIGHT VALIGN=TOP WIDTH="2%"><img SRC="../../images/Adarrow.gif" BORDER=0 height=16 width=16></td>
99 :    
100 :     <td WIDTH="98%"><b>Drawbacks</b>
101 :     <ul>
102 :     <li>There are now 2 files to maintain - Now the messages.properties and the java file must be kept in sync. There
103 :     is an opportunity for tooling to help with this; a validation tool could indicate problems with markers. Currently
104 :     there are debug options which log entries which exsit in one file but not the other.</li>
105 :     </ul>
106 :     <p>&nbsp;
107 :     </p>
108 :     </td>
109 :     </tr>
110 :    
111 :     <tr>
112 :     <td ALIGN=LEFT VALIGN=TOP COLSPAN="2" BGCOLOR="#0080C0"><b><font face="Arial,Helvetica" color="#FFFFFF">File Formats</font></b></td>
113 :     </tr>
114 :     <tr>
115 :     <td ALIGN=RIGHT VALIGN=TOP WIDTH="2%"><img SRC="../../images/Adarrow.gif" BORDER=0 height=16 width=16></td>
116 :    
117 :     <td WIDTH="98%"><p><b>Client Code</b></p>
118 :     Old Code:
119 :     <p>
120 :     <pre><code>public class MyClass {
121 :     &nbsp;&nbsp;&nbsp;public void myMethod() {
122 :     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String message;
123 :     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...
124 :     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// no args
125 :     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;message = Messages.getString("key.one"); //$NON-NLS-1$
126 :     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...
127 :     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// bind one arg
128 :     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;message = MessageFormat.format(Messages.getString("key.two"), new Object[] {"example usage"}); //$NON-NLS-1$ //$NON-NLS-2$
129 :     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...
130 :     &nbsp;&nbsp;&nbsp;}
131 :     }</code></pre>
132 :     </p>
133 :    
134 :     New Code:
135 :     <p><pre><code>public class MyClass {
136 :     &nbsp;&nbsp;&nbsp;public void myMethod() {
137 :     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String message;
138 :     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...
139 :     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// no args
140 :     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;message = Messages.key_one;
141 :     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...
142 :     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// bind one arg
143 :     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;message = NLS.bind(Messages.key_two, "example usage"); //$NON-NLS-1$
144 :     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...
145 :     &nbsp;&nbsp;&nbsp;}
146 :     }</code></pre></p>
147 :     <p>&nbsp;</p>
148 :     </td>
149 :     </tr>
150 :     <tr>
151 :     <td ALIGN=RIGHT VALIGN=TOP WIDTH="2%"><img SRC="../../images/Adarrow.gif" BORDER=0 height=16 width=16></td>
152 :    
153 :     <td WIDTH="98%"><p><b>Messages.java</b></p>
154 :     Old Code:
155 :     <pre><code>public class Messages {
156 :     &nbsp;&nbsp;&nbsp;private static final String BUNDLE_NAME = &quot;org.eclipse.core.utils.messages&quot;; //$NON-NLS-1$
157 :     &nbsp;&nbsp;&nbsp;private static final ResourceBundle bundle = ResourceBundle.getBundle(BUNDLE_NAME);
158 :     &nbsp;&nbsp;&nbsp;
159 :     &nbsp;&nbsp;&nbsp;public static String getString(String key) {
160 :     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try {
161 :     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return bundle.getString(key);
162 :     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} catch (MissingResourceException e) {
163 :     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return key;
164 :     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
165 :     &nbsp;&nbsp;&nbsp;}
166 :     }</code></pre>
167 :    
168 :     New Code:
169 :     <pre><code>public class Messages extends NLS {
170 :     &nbsp;&nbsp;&nbsp;private static final String BUNDLE_NAME = &quot;org.eclipse.core.utils.messages&quot;; //$NON-NLS-1$
171 :     &nbsp;&nbsp;&nbsp;
172 :     &nbsp;&nbsp;&nbsp;public static String key_one;
173 :     &nbsp;&nbsp;&nbsp;public static String key_two;
174 :     &nbsp;&nbsp;&nbsp;...
175 :     &nbsp;&nbsp;&nbsp;static {
176 :     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NLS.initializeMessages(BUNDLE_NAME, Messages.class);
177 :     &nbsp;&nbsp;&nbsp;}
178 :     }</code></pre>
179 :     <p>&nbsp;</p>
180 :     </td>
181 :     </tr>
182 :     <tr>
183 :     <td ALIGN=RIGHT VALIGN=TOP WIDTH="2%"><img SRC="../../images/Adarrow.gif" BORDER=0 height=16 width=16></td>
184 :    
185 :     <td WIDTH="98%"><p><b>messages.properties</b></p>
186 :     Old Code:
187 :     <pre><code>key.one = Hello world.
188 :     key.two = This is an {0} of binding with one argument.
189 :     </code></pre>
190 :     New Code:
191 :     <pre><code>key_one = Hello world.
192 :     key_two = This is an {0} of binding with one argument.
193 :     </code></pre>
194 :     </p>
195 :     <p>&nbsp; </p></td>
196 :     </td>
197 :     </tr>
198 :     <tr>
199 :     <td ALIGN=LEFT VALIGN=TOP COLSPAN="2" BGCOLOR="#0080C0"><b><font face="Arial,Helvetica" color="#FFFFFF">Tools</font></b></td>
200 :     </tr>
201 :     <tr>
202 :     <td ALIGN=RIGHT VALIGN=TOP WIDTH="2%"><img SRC="../../images/Adarrow.gif" BORDER=0 height=16 width=16></td>
203 :    
204 :     <td WIDTH="98%"><b>Conversion</b> <p>We have written a tool which aids in
205 :     converting from the basic Java resource bundle look-up mechanism, to the
206 :     new format. </p>
207 :     <p><em>Note that the message bundle access class is replaced when the tool
208 :     is run. If you define extra code, constants, etc in that class then please
209 :     read the notes below to ensure that you don't have problems.</em></p>
210 :     <p>Here are the steps to use when converting your code.</p>
211 :     <ul>
212 :     <li>Download <a href="../../downloads/tools/message_bundles/com.example.nls_1.0.0.zip">version 1.0.0</a>
213 :     and install the plug-in.</li>
214 :     <li>Run Eclipse.</li>
215 :     <li>Synchronize with the repository. (you will be using the Synchronize
216 :     view as your compare browser to view changes)</li>
217 :     <li>Select your message bundle access class. (e.g. the class which has
218 :     the <code>#getString(String)</code> method in it)</li>
219 :     <li>From the context menu, choose &quot;Convert Message Bundle&quot;.</li>
220 :     <li>Choose the class's associated .properties file from the resulting
221 :     &quot;Open Resource...&quot; dialog.</li>
222 :     <li>Use the Synchronize view to review the changes.</li>
223 :     <li>Release the new code.</li>
224 :     </ul>
225 :     <p><strong>Notes:</strong> </p>
226 :     <p>When using the NLS tooling from previous Eclipse releases, the java file
227 :     which was created had the format of the &quot;old&quot; Messages.java
228 :     file as described above. (basic class with <code>#getString(String)</code> method) Some plug-in owners have created extra helper
229 :     methods on the class to aid in their message bundle lookup. Since the
230 :     conversion tool has only basic functionality, these plug-in developers
231 :     must perform a couple of extra steps before running the tool.</p>
232 :     <p>Essentially what you want to do is get your java file into the basic
233 :     template form. This is possible via using existing refactorings. For instance,
234 :     if your class defines a method like this:</p>
235 :     <pre><code>public String getString(String key, Object binding) {
236 :     &nbsp;&nbsp;&nbsp;return MessageFormat.format(getString(key), new Object[] {binding});
237 :     }</code></pre>
238 :     <p>Then you want to do the following:</p>
239 :     <ol>
240 :     <li>Change the method body to be: <code>return NLS.bind(getString(key), binding);</code></li>
241 :     <li>Select the method name and from the context menu choose the &quot;Inline&quot;
242 :     refactoring. This will replace calls to this method in your code with
243 :     calls to the code in step 1.</li>
244 :     <li>Run the tool. Since only calls to <code>#getString(String)</code> exist now,
245 :     the tool will run sucessfully.</li>
246 :     </ol>
247 :     </tr>
248 :     </table>
249 :    
250 :    
251 :     </body>
252 :     </html>