Java tutorial
/* * Copyright 2013 Maxime Falaize. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.mfalaize.ant; import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.ResourceBundle; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.io.FileUtils; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.Project; import org.apache.tools.ant.taskdefs.MatchingTask; /** * Ant task to translate files such as HTML files easily from the build process. * It replaces all occurrences of the * <code>$${key}</code> pattern by the corresponding in properties or java * files. * <p> * The task extends of {@link MatchingTask} which allows you to use commons * include and exclude tags to select your processed files. * * @author Maxime Falaize * @version 1.0 * @since 1.0 */ public class LocalizeTask extends MatchingTask { /** * The pattern matches strings such as * <code>$${key}</code>. */ private static final String LOCALIZE_PATTERN = "(\\$\\$\\{\\s*)([\\w\\._-]+)(\\s*\\})"; /** * The pattern matches the line which contains the localize-task.js script * inclusion. */ private static final String LOCALIZE_JS_PATTERN = "<script\\s*src=\"localize-task\\.(min\\.)?js\"\\s*/?>(</script>)?"; /** * The project directory. Default is the current working directory. */ private File projectDirectory = new File("."); /** * The base name of the resource bundle, a fully qualified class name. * Default to messages. */ private String resourceBundleBaseName = "messages"; /** * Encoding of the files to translate. Default is UTF-8. */ private String encoding = "UTF-8"; /** * The directory which contains all of the files to translate. Default to * the {@link projectDirectory}. */ private File translateDirectory = projectDirectory; /** * The directory which will contain all of the files generated by this ant * task. Default to the {@link projectDirectory}. */ private File targetDirectory = projectDirectory; public void setProjectDirectory(File projectDirectory) { this.projectDirectory = projectDirectory; } public void setResourceBundleBaseName(String resourceBundleBaseName) { this.resourceBundleBaseName = resourceBundleBaseName; } public void setEncoding(String encoding) { this.encoding = encoding; } public void setTranslateDirectory(File translateDirectory) { this.translateDirectory = translateDirectory; } public void setTargetDirectory(File targetDirectory) { this.targetDirectory = targetDirectory; } /** * Get the list of available * <code>ResourceBundle</code> in the project. * * @return The list of <code>ResourceBundle</code> available in the project * to build. * @throws BuildException when the <code>ResourceBundle</code> cannot be * find. */ private List<ResourceBundle> getAvailableResourceBundles() throws BuildException { List<ResourceBundle> list = new ArrayList<ResourceBundle>(); for (Locale locale : Locale.getAvailableLocales()) { try { ResourceBundle resourceBundle = ResourceBundle.getBundle(resourceBundleBaseName, locale); if (locale.equals(resourceBundle.getLocale())) { list.add(resourceBundle); } else { log(String.format("No resource bundle exists for the locale %s. Continue...", locale.getLanguage()), Project.MSG_VERBOSE); } } catch (Throwable ex) { throw new BuildException(ex); } } return list; } @Override public void execute() throws BuildException { for (ResourceBundle resourceBundle : getAvailableResourceBundles()) { // Create the directory in which store all the files translated for this resourceBundle File directory = new File(targetDirectory + File.separator + resourceBundle.getLocale().getLanguage()); if (!directory.mkdirs()) { log(String.format("Cannot create directory %s.", directory.getAbsolutePath()), Project.MSG_ERR); continue; } else { log(String.format("Creating directory for locale %s.", resourceBundle.getLocale().getLanguage()), Project.MSG_VERBOSE); } DirectoryScanner ds = getDirectoryScanner(translateDirectory); String[] files = ds.getIncludedFiles(); log(String.format("Translating %d files for locale %s...", files.length, resourceBundle.getLocale().getLanguage())); for (int i = 0; i < files.length; i++) { File file = new File(translateDirectory + File.separator + files[i]); log(String.format("Translating %s...", files[i]), Project.MSG_VERBOSE); try { String fileString = FileUtils.readFileToString(file, encoding); Pattern pattern = Pattern.compile(LOCALIZE_PATTERN); Matcher matcher = pattern.matcher(fileString); while (matcher.find()) { String key = matcher.group(2); fileString = matcher.replaceFirst(resourceBundle.getString(key)); log(String.format("Replacing occurrence of %s by %s.", matcher.group(), resourceBundle.getString(key)), Project.MSG_DEBUG); matcher = pattern.matcher(fileString); } // localize-task.js inclusion removal matcher = Pattern.compile(LOCALIZE_JS_PATTERN).matcher(fileString); if (matcher.find()) { fileString = matcher.replaceFirst(""); log("Removing the localize-task.js inclusion.", Project.MSG_DEBUG); } String newFilePath = directory.getAbsolutePath() + File.separator + org.apache.tools.ant.util.FileUtils.getRelativePath(projectDirectory, file); FileUtils.writeStringToFile(new File(newFilePath), fileString, encoding); } catch (Throwable ex) { log(String.format("An exception occured : %s", ex.getMessage()), Project.MSG_ERR); throw new BuildException(ex); } } } } }