16.3. Using Fragments
All the translated properties files could be included in the main plug-in, but this is less than ideal in a situation where the translations will be delivered later than the product itself. If all the translated files need to be included with the main plug-in, you would either need to delay the release of the main plug-in or rerelease it when the translations are available. Fortunately, Eclipse includes a mechanism called a plug-in fragment that provides an elegant solution to this problem.
Fragments are used to extend the functionality of another plug-in. Fragments are typically used to supply alternative language packs, maintenance updates, and platform-specific implementation classes. When a fragment is loaded, its features and capabilities are merged with those of the base plug-in such that they appear to have come from the base plug-in itself.
The developer does not need to know whether the plug-in or one of its fragments contributes a specific resource because the plug-in class loader handles this transparently. This makes it easy to deliver translated versions of plug-in files (e.g., HTML, XML, INI, and properties files) independently of the main plug-in.
The properties files follow the resource bundle-naming rules (as noted earlier). Other resources, such as HTML, XML, and INI files are placed into nl/<language> or nl/<language>/<country> directories, where <language> and <country> represent the two-letter codes used to signify the language and country (this directory structure was first introduced in Section 15.2.3, Table of contents (toc) files, on page 548).
Fragments can also be used for smoothing out differences between different versions of Eclipse (see Section 188.8.131.52, Fragments, on page 698) and for accessing internal classes and methods (see Section 20.2.6, Using fragments, on page 714).
16.3.1. New Fragment Project wizard
Creating a new fragment is easy using the New Fragment Project wizard. From the File menu, select New > Project to launch the new project wizard (see Figure 16-8). On this first page of the wizard, select Plug-in Development > Fragment Project, followed by the Next button.
Figure 16-8. New Project wizard with Fragment Project selected.
On the next page of the wizard (see Figure 16-9), enter the name of the project; in this case, it should be "com.qualityeclipse.favorites.nl1", which is the same as the plug-in fragment identifier. The Eclipse convention is to name a plug-in fragment project that contributes national language support to a base plug-in with the same name as the base plug-in plus the suffix ".nl1". Click the Next button.
Figure 16-9. New Fragment Project wizard.
The Fragment Content page (see Figure 16-10) provides fields to name the fragment, set its ID and version number, and identify the plug-in ID and version that it extends. Use the Browse... button to select the plug-in, if necessary. In this case, you want to extend the existing com.qualityeclipse.favorites plug-in (see Figure 16-11).
Figure 16-10. Required data for initial fragment files.
Figure 16-11. The manifest editor for the fragment.
Choose the Greater or Equal option and click the Finish button to complete the wizard and generate the fragment manifest file.
Double-clicking in the fragment manifest file, MANIFEST.MF, will open the fragment manifest editor (see Figure 16-12). The editor looks very similar to the plug-in manifest editor with Overview, Dependencies, Runtime, Extension Points, etc. pages.
Figure 16-12. Fragment manifest editor.
If you switch to the Runtime page (see Figure 16-13), you will see that nothing is included in the runtime classpath for the fragment. Various files, such as translated HTML, XML, and INI files, are located in specially named subdirectories based on the associated locale (language and country combination).
Figure 16-13. Fragment Runtime Information page.
To get those directories to show up in the runtime classpath, click the New... button to add a "New Library" entry to the list. Right-click on that entry and Rename it to "$nl$/". This is special syntax that will cause the system to substitute the correct classpath entry at runtime based on the current locale. If the locale is set to Germany, for example, "$nl$" would be substituted by "de", and the "de/" subdirectory would be added to the runtime path.
Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Favorites NLS Fragment Bundle-SymbolicName: com.qualityeclipse.favorites.nl1 Bundle-Version: 1.0.0 Bundle-Vendor: QualityEclipse Fragment-Host: com.qualityeclipse.favorites; bundle-version="1.0.0" Bundle-Localization: plugin Bundle-ClassPath: $nl$/
This source is very similar to what you would expect to see for a plug-in. The first major difference is that fragments don't have their own plug-in lifecycle (they conform to the lifecycle of their associated plug-in), and thus, they don't need their own Bundle-Activator attribute. The second difference is that the fragment does not declare any of its own dependencies (again, they are inherited from the associated plug-in).
The interesting attributes relative to those found in full plug-ins are the Fragment-Host and the bundle-version attributes. The Fragment-Host identifies the plug-in that this fragment will extend. The bundle-version specifies the version of the target plug-in that this fragment expects to be able to extend.
The last thing you need to do is add all the translated files to the appropriate directories within the fragment project folder (see Figure 16-14). Assuming that you want to supply German and French translations of various files, the project would have nl/de and nl/fr directories to contain any translated HTML, XML, and INI files (like those mentioned in Section 15.2.3, Table of contents (toc) files, on page 548).
Figure 16-14. Fragment project contents.
The translated versions of the plugin.properties files are placed at the root of the fragment, and the translated versions of the messages.properties files are placed in the com.qualityeclipse.favorites.views directory.