001/* 002 * Licensed under the Apache License, Version 2.0 (the "License"); 003 * you may not use this file except in compliance with the License. 004 * You may obtain a copy of the License at 005 * 006 * http://www.apache.org/licenses/LICENSE-2.0 007 * 008 * Unless required by applicable law or agreed to in writing, software 009 * distributed under the License is distributed on an "AS IS" BASIS, 010 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 011 * See the License for the specific language governing permissions and 012 * limitations under the License. 013 */ 014package org.apache.wiki; 015 016import java.io.FileNotFoundException; 017import java.io.IOException; 018import java.util.ArrayList; 019import java.util.Collections; 020import java.util.Enumeration; 021import java.util.HashMap; 022import java.util.Iterator; 023import java.util.List; 024import java.util.Map; 025import java.util.Properties; 026import java.util.TreeSet; 027 028/** 029 * Simple utility that shows you a sorted list of property differences between 030 * the 'default en' and a given i18n file. It also warns if there are any duplicates. 031 * <p> 032 * The first argument is the language, and it is mandatory. 033 * The second argument is the path. If the path is not defined, uses current path (.) 034 * <p> 035 * For example (if you're compiling your classes to "classes"): 036 * <code> 037 * java -cp classes TranslationsCheck fi 038 * </code> 039 * 040 */ 041public class TranslationsCheck 042{ 043 private static final TreeSet<String> allProps = new TreeSet<String>(); // sorted, no duplicates 044 private static final TreeSet<String> duplProps = new TreeSet<String>(); 045 046 // Change these to your settings... 047 static String base = "."; 048 static String suffix = null; 049 050 public static void main(String[] args) throws IOException 051 { 052 if( args.length == 0 ) 053 { 054 System.out.println("Usage: java TranslationsCheck <language> [<path>]"); 055 System.out.println("Example: java TranslationsCheck nl [jspwiki-main/src/main/resources]"); 056 return; 057 } 058 059 suffix = args[0]; 060 061 if( args.length >= 2 ) 062 { 063 base = args[1]; 064 } 065 066 System.out.println("Using code base " + Release.VERSTR); 067 System.out.println("Internationalization property file differences between 'default en' and '" + suffix + "' following:\n"); 068 069 try 070 { 071 diff("/CoreResources.properties", "/CoreResources_" + suffix + ".properties"); 072 detectDuplicates("/CoreResources_" + suffix + ".properties"); 073 } 074 catch( FileNotFoundException e ) 075 { 076 System.err.println("Unable to locate "+"/CoreResources_" + suffix + ".properties"); 077 } 078 079 try 080 { 081 diff("/templates/default.properties", "/templates/default_" + suffix + ".properties"); 082 detectDuplicates("/templates/default_" + suffix + ".properties"); 083 } 084 catch( FileNotFoundException e ) 085 { 086 System.err.println("Unable to locate "+"/templates/default_" + suffix + ".properties"); 087 } 088 089 try 090 { 091 diff("/plugin/PluginResources.properties", "/plugin/PluginResources_" + suffix + ".properties"); 092 093 detectDuplicates("/plugin/PluginResources_" + suffix + ".properties"); 094 095 System.out.println("Duplicates overall (two or more occurences):"); 096 System.out.println("--------------------------------------------"); 097 Iterator< String > iter = duplProps.iterator(); 098 if (duplProps.size() == 0) 099 System.out.println("(none)"); 100 else 101 while (iter.hasNext()) 102 System.out.println(iter.next()); 103 System.out.println(); 104 } 105 catch( FileNotFoundException e ) 106 { 107 System.err.println("Unable to locate "+"/plugin/PluginResources_" + suffix + ".properties"); 108 } 109 110 System.out.println("NOTE: Please remember that dependent on the usage of these i18n files, outdated " + 111 "properties maybe should not be deleted, because they may be used by previous releases. " + 112 "Moving them to a special section in the file may be the better solution."); 113 } 114 115 public static Map< String, Integer > diff(String source1, String source2) throws FileNotFoundException, IOException 116 { 117 int missing = 0, outdated = 0; 118 // Standard Properties 119 Properties p1 = new Properties(); 120 121 p1.load( TranslationsCheck.class.getClassLoader().getResourceAsStream( base + source1 ) ); 122 123 Properties p2 = new Properties(); 124 p2.load( TranslationsCheck.class.getClassLoader().getResourceAsStream( base + source2 ) ); 125 126 String msg = "Checking " + source2 + "..."; 127 System.out.println(msg); 128 129 Iterator< String > iter = sortedNames(p1).iterator(); 130 while (iter.hasNext()) 131 { 132 String name = iter.next(); 133 String value = p1.getProperty(name); 134 135 if (p2.get(name) == null) 136 { 137 missing++; 138 if (missing == 1) 139 { 140 System.out.println("\nMissing:"); 141 System.out.println("--------"); 142 } 143 System.out.println(name + " = " + value); 144 } 145 } 146 if (missing > 0) 147 { 148 System.out.println(); 149 } 150 151 iter = sortedNames(p2).iterator(); 152 while (iter.hasNext()) 153 { 154 String name = iter.next(); 155 String value = p2.getProperty(name); 156 157 if (p1.get(name) == null) 158 { 159 outdated++; 160 if (outdated == 1) 161 { 162 System.out.println("\nOutdated or superfluous:"); 163 System.out.println("------------------------"); 164 } 165 System.out.println(name + " = " + value); 166 } 167 } 168 if (outdated > 0) 169 { 170 System.out.println(); 171 } 172 173 Map< String, Integer > diff = new HashMap< String, Integer >( 2 ); 174 diff.put( "missing", missing ); 175 diff.put( "outdated", outdated ); 176 return diff; 177 } 178 179 private static List<String> sortedNames(Properties p) 180 { 181 List<String> list = new ArrayList<String>(); 182 Enumeration<?> iter = p.propertyNames(); 183 while (iter.hasMoreElements()) 184 { 185 list.add( (String)iter.nextElement() ); 186 } 187 188 Collections.sort(list); 189 return list; 190 } 191 192 public static int detectDuplicates(String source) throws IOException 193 { 194 Properties p = new Properties(); 195 p.load( TranslationsCheck.class.getClassLoader().getResourceAsStream( base + source ) ); 196 197 Enumeration<?> iter = p.propertyNames(); 198 String currentStr; 199 while (iter.hasMoreElements()) 200 { 201 currentStr = (String) iter.nextElement(); 202 if (!allProps.add(currentStr)) 203 duplProps.add(currentStr); 204 } 205 return duplProps.size(); 206 } 207 208}