Skip to content
This repository has been archived by the owner on Nov 9, 2017. It is now read-only.

Commit

Permalink
Merge pull request #334 from zanata/gwt-i18n
Browse files Browse the repository at this point in the history
enable localization of gwt resources
  • Loading branch information
carlosmunoz committed Jan 31, 2014
2 parents 1edf7f4 + 09821a1 commit 3c935d4
Show file tree
Hide file tree
Showing 16 changed files with 299 additions and 136 deletions.
8 changes: 8 additions & 0 deletions pom.xml
Expand Up @@ -739,6 +739,14 @@
<artifactId>jcabi-mysql-maven-plugin</artifactId>
<version>0.4</version>
</plugin>
<plugin>
<groupId>org.codehaus.gmaven</groupId>
<artifactId>gmaven-plugin</artifactId>
<version>1.5</version>
<configuration>
<providerSelection>2.0</providerSelection>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
Expand Down
1 change: 1 addition & 0 deletions zanata-war/.gitignore
@@ -0,0 +1 @@
.zanata-cache
71 changes: 71 additions & 0 deletions zanata-war/pom.xml
Expand Up @@ -427,6 +427,19 @@
</configuration>
</plugin>

<plugin>
<!-- server pom has same plugin definition with different includes -->
<groupId>org.zanata</groupId>
<configuration>
<srcDir>${project.build.directory}/gwt-extra/webtrans</srcDir>
<transDir>src/main/resources/zanata-editor</transDir>
<includes>**/*.properties</includes>
<excludes>**/*_default.properties</excludes>
</configuration>
<artifactId>zanata-maven-plugin</artifactId>
<version>3.3.0</version>
</plugin>

<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
Expand Down Expand Up @@ -1040,6 +1053,64 @@

</profile>

<profile>
<id>gwt-i18n</id>
<activation>
<property>
<name>gwt-i18n</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>gwt-maven-plugin</artifactId>
<executions>
<execution>
<id>generate-i18n</id>
<goals>
<goal>compile</goal>
</goals>
<!--here we bind it to generate-test-resource because we want it to happen before the real compile(prepare-package) and able to do its job -->
<phase>generate-test-resources</phase>
<configuration>
<module>org.zanata.webtrans.ApplicationI18n</module>
<extra>${project.build.directory}/gwt-extra</extra>
<extraParam>true</extraParam>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.gmaven</groupId>
<artifactId>gmaven-plugin</artifactId>
<configuration>
<!-- the groovy.script will be given by command line arg -->
<!-- at the moment it's used in zanata.xml as command hook -->
<source>${pom.basedir}/src/etc/${groovy.script}</source>
</configuration>
<executions>
<execution>
<phase>generate-test-resources</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<classpath>
<element>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</element>
</classpath>
<source>${pom.basedir}/src/etc/PrepareGWTI18NProperties.groovy</source>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>

</profiles>

<dependencies>
Expand Down
73 changes: 73 additions & 0 deletions zanata-war/src/etc/FillInTranslationGap.groovy
@@ -0,0 +1,73 @@
import com.google.common.io.Files

// This script will used combine pulled translation files from Zanata server and GWT generated skeleton file.
// This will enable GWT to compile locale permutation for not 100% translated locales.
// It's used in zanata.xml as command hook.

File gwtGenDir = new File(project.build.directory + "/gwt-extra/webtrans")
assert gwtGenDir.isDirectory() :"target/gwt-extra/webtrans does not exist. You need to have source available. Either pull with source or re-generate source again."

File basedir = pom.basedir
// zanata pull target dir is here
File pulledTargetDir = new File(basedir.absolutePath + "/src/main/resources/zanata-editor")

// find properties file with underscore (translation properties)
def targetNames = new FileNameByRegexFinder().
getFileNames(pulledTargetDir.absolutePath, /.+_.+\.properties$/)

def targetProps = targetNames.collect {
new File(it)
}

def ln = System.getProperty("line.separator")

Map<String, Properties> translationMap = targetProps.collectEntries {
Properties source = new Properties()
it.withReader("UTF-8") {
source.load(it)
}
[it.name, source]
}

log.info("translation map: {} \n\n\n", translationMap.keySet())

// get all GWT generated translation skeletons
def genPropNames = new FileNameByRegexFinder().
getFileNames(gwtGenDir.absolutePath, /\w+\.properties$/, /_default.properties$/)

genPropNames.each {
// we move GWT generated skeletons to project build class path but not in source tree
def relativePath = it - gwtGenDir
def skeleton = new File(it)
def finalOutput = new File("$project.build.outputDirectory/$relativePath")
finalOutput.getParentFile().mkdirs()
log.debug("finalOutput: {}", finalOutput.absolutePath)
Files.copy(skeleton, finalOutput)

def translation = translationMap.get(skeleton.name)
if (!translation) {
log.info("no translation found for {}", skeleton.name)
return
}
def lines = finalOutput.readLines("UTF-8")
lines.eachWithIndex { line, index ->
def pair = line.split(/=/)
if (pair.size() != 2) {
return
}
String key = pair[0]
def textFlowTarget = translation.get(key)
if (textFlowTarget) {
log.debug("fill in {} with translation: {}", key, textFlowTarget)
lines.set(index, "$key=$textFlowTarget")
}
}

finalOutput.withPrintWriter("UTF-8") { writer ->
lines.each {
writer.append("$it$ln")
}
}
log.info("processed {}", skeleton.name)
}

96 changes: 96 additions & 0 deletions zanata-war/src/etc/PrepareGWTI18NProperties.groovy
@@ -0,0 +1,96 @@
import com.google.common.io.Files

// This script will rename GWT generated properties for Zanata to use.
log.info "===== Preparing GWT generated properties files ====="

def gwtGenDir = new File(project.build.directory + "/gwt-extra/webtrans")

assert gwtGenDir.isDirectory()

def nameFilter = { dir, name ->
name.endsWith(".properties")
} as FilenameFilter

def properties = gwtGenDir.listFiles(nameFilter)


if (!properties) {
log.info "no properties found. quit."
return
}
// scrip off the file name part to get package name
def packageName = properties[0].name.replaceAll(/\.\w+\.properties/, "")
def packagePath = packageName.replaceAll(/\./, "/")

def resourceDir = new File("$gwtGenDir.absolutePath/$packagePath")
resourceDir.mkdirs()

int sourceCount = 0
int targetCount = 0

properties.each {
if (it.name.endsWith("_default.properties")) {
log.debug " * found source: $it.name"
// change the name of the file
def fileName = (it.name - "$packageName.").replace("_default", "")
def destFile = new File(resourceDir, fileName)
log.info " moved to: $destFile"
Files.move(it, destFile)
sourceCount++
} else {
log.debug " * found target: $it.name"
def fileName = (it.name - "$packageName.")
def destFile = new File(resourceDir, fileName)
// we ALWAYS copy generated target skeleton to make sure target is in sync if source has changed.
// Also to make sure enabled locale (in Application.gwt.xml) has something to display if translation is not yet available.
// Later we will base on pulled translation to repopulate the file.
// see FillInTranslationGap.groovy
log.info " moved to :$destFile"
Files.move(it, destFile);
targetCount++
}
}

log.info "Generated $sourceCount source(s) and $targetCount target(s) in $resourceDir"
log.info "===== Prepared GWT generated properties files ====="

// below procedure is to fix GWT's bizarre behavior.
// if we have properties files on classpath (i.e. compile with extra already),
// the second time GWT compiler produces properties file will output plural forms in properties but some of them are empty.
// It will be empty if:
// 1. the required plural form for that language is not defined in java interface. i.e. in Ukranian you ought to have "one", "few", "other" defined in @AlternateMessage.
// see com.google.gwt.i18n.client.impl.plurals.DefaultRule_x1_x234_n
// 2. in java interface it uses complex plural combination. i.e. having multiple @PluralCount in parameters.
// see org.zanata.webtrans.client.resources.WebTransMessages.showingResultsForProjectWideSearch
// First one won't cause any trouble. We can ignore it.
// Second one may not be fixable. The GWT doc says the plural form is still a work in progress. I don't know how it works either.
// We can either add extra plural count in the [] i.e. turn [one] to [one|one]. But Zanata doesn't support mismatch source and target.
// So I removing those extra plural entries which allows GWT to compile again (with a warning).
// see https://github.com/zanata/zanata-server/wiki/Localize-Zanata for more detail.

def filter = {
it.name.endsWith(".properties")
} as FileFilter
properties = resourceDir.listFiles(filter)

def ln = System.getProperty("line.separator")

properties.each {
def lines = it.readLines("UTF-8")
boolean touched = false
lines.eachWithIndex { line, index ->
if (line.matches(/.+=$/)) {
log.info("found and removed empty plural entry: {}", line)
lines.set(index, "")
touched = true
}
}
if (touched) {
log.info("processed {}", it.name)
it.withPrintWriter("UTF-8") { writer ->
lines.each {
writer.append("$it$ln")
}
}
}
}
33 changes: 0 additions & 33 deletions zanata-war/src/etc/zanata-defaultconfig.properties

This file was deleted.

34 changes: 0 additions & 34 deletions zanata-war/src/etc/zanata.properties

This file was deleted.

Expand Up @@ -49,6 +49,10 @@
<source path="shared" />

<inherits name="com.google.gwt.i18n.I18N" />
<extend-property name="locale" values="en,qc" />
<!-- if we want to include new locale in our app, add new extend-property value and then add to ApplicationI18n.gwt.xml-->
<!-- at the moment we have included locales in faces-config.xml -->
<extend-property name="locale" values="en,ja,zh_Hant_TW,uk,qc" />
<!--uncomment once translated -->
<!--<set-property name="locale" value="en,ja,zh_Hant_TW,uk" />-->
<set-property-fallback name="locale" value="en" />
</module>
@@ -0,0 +1,13 @@
<!--
set-property-fallback is missing from the DTD:
<!DOCTYPE module PUBLIC "//gwt-module/" "http://google-web-toolkit.googlecode.com/svn/tags/2.0.3/distro-source/core/src/gwt-module.dtd">
-->
<module rename-to="webtrans">
<inherits name="org.zanata.webtrans.Application" />
<set-property name="user.agent" value="safari" />
<extend-property name="log_level" values="DEBUG" />
<set-property name="log_level" value="DEBUG" />

<!-- add locales to generate different properties template-->
<set-property name="locale" value="default,en,ja,zh_Hant_TW,uk" />
</module>
Expand Up @@ -124,10 +124,12 @@ String statusBarPercentageHrs(String approved, String remainingHours,
String searchFoundResultsInDocuments(@PluralCount int numDocs);

@DefaultMessage("Showing results for search \"{0}\" ({1} text flows in {2} documents)")
@AlternateMessage({ "one|one",
"Showing results for search \"{0}\" (1 text flow in 1 document)",
"other|one",
"Showing results for search \"{0}\" ({1} text flows in 1 document)" })
// @formatter:off
@AlternateMessage({
"one|one", "Showing results for search \"{0}\" (1 text flow in 1 document)",
"other|one", "Showing results for search \"{0}\" ({1} text flows in 1 document)"
})
// @formatter:on
String showingResultsForProjectWideSearch(String searchString,
@PluralCount int textFlows, @PluralCount int documents);

Expand Down Expand Up @@ -465,7 +467,7 @@ String undoUnsuccessful(@PluralCount int unsuccessfulCount,
@DefaultMessage("Text contain in both search term and result")
String tmPlainTextDesc();

@DefaultMessage("New replacement text ")
@DefaultMessage("New replacement text")
String searchReplaceInsertTagDesc();

@DefaultMessage("Old text to be replaced")
Expand Down

0 comments on commit 3c935d4

Please sign in to comment.