Configuring localization

Let's show how flex-mojos can be used to generate resource-bundles.

Before we start, it is necessary to understand how flex localization works. I strongly recommend you read thisto understand how Flex localization works. With this in mind we can see how to use flex-mojos to create localized applications.

Flex support 2 localization styles: Compiled Localization and Runtime Localization.

Compiled Localization

Here you can get the source for FlightReservationSamples 1.

Download FlightReservation1 Sample and import it to FlexBuilder.

To compile Sample1 with flex-mojos, we need to add a pom:

<project>
  <modelVersion>4.0.0</modelVersion>

  <parent>
    <groupId>org.sonatype.flexmojos</groupId>
    <artifactId>flexmojos-flex-super-pom</artifactId>
    <version>%{flexmojos.version}</version>
  </parent>

  <groupId>com.adobe.flex.samples</groupId>
  <artifactId>FlightReservation1</artifactId>
  <version>1.0-SNAPSHOT</version>

  <packaging>swf</packaging>

  <build>
    <sourceDirectory>src</sourceDirectory>
    <plugins>
      <plugin>
        <groupId>org.sonatype.flexmojos</groupId>
        <artifactId>flexmojos-maven-plugin</artifactId>
        <configuration>
          <sourceFile>FlightReservation1.mxml</sourceFile>
          <resourceBundlePath>${basedir}/locale/{locale}</resourceBundlePath>
          <compiledLocales>
            <locale>en_US</locale>
            <locale>ja_JP</locale>
          </compiledLocales>
        </configuration>
      </plugin>
    </plugins>
  </build>

</project>
  1. resourceBundlePath: folder where .properties files are located.
    locale is replaced at runtime by locale name. This is the flex compiler behavior.
  2. compiledLocales: list of locales to be embedded in the compiled file.

This project will produce only one artifact, with everything embedded (meaning a bigger file).

Runtime Localization

Lets do the second sample. Download it from here. Again, import it into FlexBuilder.

Another pom is required for this project:

<project>
  <modelVersion>4.0.0</modelVersion>

  <parent>
    <groupId>org.sonatype.flexmojos</groupId>
    <artifactId>flexmojos-flex-super-pom</artifactId>
    <version>%{flexmojos.version}</version>
  </parent>

  <groupId>com.adobe.flex.samples</groupId>
  <artifactId>FlightReservation2</artifactId>
  <version>1.0-SNAPSHOT</version>

  <packaging>swf</packaging>

  <build>
    <sourceDirectory>src</sourceDirectory>
    <plugins>
      <plugin>
        <groupId>org.sonatype.flexmojos</groupId>
        <artifactId>flexmojos-maven-plugin</artifactId>
        <configuration>
          <resourceBundlePath>${basedir}/locale/{locale}</resourceBundlePath>
          <runtimeLocales>
            <locale>en_US</locale>
            <locale>ja_JP</locale>
          </runtimeLocales>
        </configuration>
      </plugin>
    </plugins>
  </build>

</project>

There is a tiny difference between the two poms: just change the <compiledLocales> node to <runtimeLocales>.

  1. resourceBundlePath: folder where .properties files are located. {locale} is replaced at runtime by locale name. This is the flex compiler behavior.
  2. runtimeLocale: list of locales to generate a resourceBundle file.

Running mvn clean install you will get 3 artifacts:[INFO] [install:install]
[INFO] Installing D:\FlightReservation2\target\FlightReservation2-1.0-SNAPSHOT.swf to c:\repository\com\adobe\flex\samples\FlightReservation2\1.0-SNAPSHOT\FlightReservation2-1.0-SNAPSHOT.swf
[INFO] Installing D:\FlightReservation2\target\FlightReservation2-1.0-SNAPSHOT-en_US.swf to c:\repository\com\adobe\flex\samples\FlightReservation2\1.0-SNAPSHOT\FlightReservation2-1.0-SNAPSHOT-en_US.swf
[INFO] Installing D:\FlightReservation2\target\FlightReservation2-1.0-SNAPSHOT-ja_JP.swf to c:\repository\com\adobe\flex\samples\FlightReservation2\1.0-SNAPSHOT\FlightReservation2-1.0-SNAPSHOT-ja_JP.swf

One unlocalized swf and two resource swfs (one per locale).

In order to run that, all files must be copied into any HTTP server with html wrappers. I don't know why, but runtime localization only run with html wrapper.

sourcePaths and resourceBundlePath

By default flexmojos can detect your localization files under src/main/locales (default for <resourceBundlePath/>), but if you override the sourcePaths to change your source directory (i.e. from the default src/main/flex to something else) you will also have to add an entry for the resource bundles!

Multi-Module SWC Localization

If you are using a multi-module maven project that uses a SWC with localization and a SWF that uses the SWC there are a few options:

  1. Use runtimeLocales in your SWC and add the Resource Bundle as a dependency in your SWF for each of your supported locales:

    SWC POM
    	<build>
    		<plugins>
    			<plugin>
    				<groupId>org.sonatype.flexmojos</groupId>
    				<artifactId>flexmojos-maven-plugin</artifactId>
    				<configuration>
    					<runtimeLocales>
    						<locale>en_US</locale>
    					</runtimeLocales>
    				</configuration>
    			</plugin>
    		</plugins>
    	</build>
    
    SWF POM
    	<dependencies>
    		<dependency>
    			<groupId>com.example</groupId>
    			<artifactId>example-swc</artifactId>
    			<version>${project.version}</version>
    			<type>swc</type>
    		</dependency>
    		<dependency>
    			<groupId>com.example</groupId>
    			<artifactId>example-swc</artifactId>
    			<version>${project.version}</version>
    			<type>rb.swc</type>
    			<classifier>en_US</classifier>
    		</dependency>
    	</dependencies>
    

Filtering Resource Bundles

Occasionally it is useful to be able to perform Maven Resources filtering on bundle files. This allows variables such as ${project.version} to be used and expanded in the resource files.

It's not possible to do this directly with flexmojos 3.8, but by moving the default locations, setting custom paths and binding to correct phases, this can be achieved. First, configure the resource plugin to do the filtering, with custom outputDirectory of ${basedir}/target/locales:

<plugin>
	<artifactId>maven-resources-plugin</artifactId>
	<executions>
		<execution>
			<id>copy-resources</id>
			<!-- here the phase you need -->
			<phase>process-resources</phase>
			<goals>
				<goal>copy-resources</goal>
			</goals>
			<configuration>
				<outputDirectory>${basedir}/target/locales</outputDirectory>
				<resources>
					<resource>
						<directory>src/main/locales</directory>
						<filtering>true</filtering>
					</resource>
				</resources>
			</configuration>
		</execution>
	</executions>
</plugin>

Then configure the resourceBundlePath to read from the new/filtered target, retaining the {locale} placeholder.

<plugin>
	<groupId>org.sonatype.flexmojos</groupId>
	<artifactId>flexmojos-maven-plugin</artifactId>
	<executions>
		<execution>
			<goals>
				<goal>compile-swf</goal>
			</goals>
			<configuration>
				...
			</configuration>
		</execution>
	</executions>
	<configuration>
		...
		<compiledLocales>
			<locale>en_US</locale>
		</compiledLocales>
		<resourceBundlePath>${basedir}/target/locales/{locale}</resourceBundlePath>
	</configuration>
</plugin>