/* * Rapid Beans Framework, SDK, Ant Tasks: CompareResourcePropertyFiles.java * * Copyright (C) 2009 Martin Bluemel * * Creation Date: 02/05/2009 * * This program is free software; you can redistribute it and/or modify it under the terms of the * GNU Lesser General Public License as published by the Free Software Foundation; * either version 3 of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * You should have received a copies of the GNU Lesser General Public License and the * GNU General Public License along with this program; if not, see <http://www.gnu.org/licenses/>. */ package org.rapidbeans.ant; import java.io.File; import java.io.FileInputStream; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Properties; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Task; /** * This Ant task compares two or more resource property files compares every * file with the other ones and generates missing expressions to the other ones * optionally with the language of your choice (if defined) and a big to do * remark. All properties in all files are written in alphabetical order. * * @author Martin Bluemel */ public final class CompareResourcePropertyFiles extends Task { /** * the common filename part of all resource property files. */ private String file = null; /** * the parent folder. */ private File dir = null; /** * Let the build fail if there is a todo. */ private boolean failontodo = false; // /** // * the preferred language in which to write empty resource properties. // */ // private String lang = null; /** * @param file * the file to set */ public void setFile(String file) { this.file = file; } /** * @param dir * the dir to set */ public void setDir(File dir) { this.dir = dir; } // /** // * @param lang the lang to set // */ // public void setLang(String lang) { // this.lang = lang; // } /** * The execute method has to be implemented from every Ant task. */ public void execute() { boolean todo = false; try { final List<File> filesList = findFiles(this.dir); final Properties[] propsArray = new Properties[filesList.size()]; final boolean[] todosArray = new boolean[filesList.size()]; int n = 0; for (File file : filesList) { final Properties props = new Properties(); final FileInputStream fis = new FileInputStream(file); props.load(fis); propsArray[n] = props; todosArray[n] = false; fis.close(); n++; } for (int i = 0; i < propsArray.length; i++) { final Properties props = propsArray[i]; for (final Object o : props.keySet()) { final String key = (String) o; for (int j = 0; j < propsArray.length; j++) { if (i != j) { final Properties otherProps = propsArray[j]; if (otherProps.getProperty(key) == null) { final String value = "TODO: TRANSLATE#" + props.getProperty(key); otherProps.setProperty(key, value); this.getProject().log( "ERROR in File: " + filesList.get(j).getAbsolutePath() + ":\n" + " property \"" + key + "\" is not defined."); todo = true; todosArray[j] = true; } } } } for (final Object o : props.keySet()) { if ((props.getProperty((String) o)).startsWith("TODO: TRANSLATE#")) { this.getProject().log( "ERROR in File: " + filesList.get(i).getAbsolutePath() + ":\n" + " Todo left for property \"" + o + "\"."); todo = true; todosArray[i] = true; } } } if (todo) { final String newline = PlatformHelper.getLineFeed(); int i = 0; for (File file : filesList) { if (!todosArray[i]) { this.getProject().log("file OK: " + file.getAbsolutePath()); i++; continue; } final List<String> keyList = new ArrayList<String>(); for (final Object key : propsArray[i].keySet()) { keyList.add((String) key); } Collections.sort(keyList); this.getProject().log("rewiriting file " + file.getAbsolutePath() + "..."); final FileWriter ow = new FileWriter(file); for (final String key : keyList) { ow.write(key); ow.write("="); ow.write(escape(propsArray[i].getProperty(key))); ow.write(newline); } ow.close(); i++; } } if (this.failontodo && todo) { throw new BuildException("Please fix TODOs in resource properties."); } } catch (IOException e) { throw new BuildException(e); } } private List<File> findFiles(final File folder) { final ArrayList<File> files = new ArrayList<File>(); for (File file : folder.listFiles()) { if (file.isDirectory()) { files.addAll(findFiles(file)); } else { if (file.getName().equals(this.file)) { files.add(file); } } } return files; } private String escape(final String s) { final StringBuffer sb = new StringBuffer(); final int len = s.length(); for (int i = 0; i < len; i++) { final char c = s.charAt(i); if (c == '\n') { sb.append("\\n"); } else { sb.append(c); } } return sb.toString(); } public void setFailontodo(boolean failontodo) { this.failontodo = failontodo; } }