1 16 package com.google.gwt.i18n.rebind.util; 17 18 import com.google.gwt.dev.util.Util; 19 import com.google.gwt.dev.util.log.PrintWriterTreeLogger; 20 import com.google.gwt.i18n.tools.I18NSync; 21 import com.google.gwt.user.rebind.ClassSourceFileComposerFactory; 22 import com.google.gwt.user.rebind.SourceWriter; 23 24 import org.apache.tapestry.util.text.LocalizedProperties; 25 26 import java.io.File ; 27 import java.io.FileInputStream ; 28 import java.io.FileNotFoundException ; 29 import java.io.FileOutputStream ; 30 import java.io.IOException ; 31 import java.io.InputStream ; 32 import java.io.OutputStreamWriter ; 33 import java.io.PrintWriter ; 34 import java.io.Writer ; 35 import java.util.ArrayList ; 36 import java.util.HashSet ; 37 import java.util.Iterator ; 38 import java.util.List ; 39 import java.util.Set ; 40 import java.util.Map.Entry; 41 import java.util.regex.Pattern ; 42 43 47 public abstract class AbstractLocalizableInterfaceCreator { 48 private static class RenameDuplicates extends ResourceKeyFormatter { 49 private Set methodNames = new HashSet (); 50 51 public String format(String key) { 52 if (methodNames.contains(key)) { 53 key += "_dup"; 54 return format(key); 55 } else { 56 methodNames.add(key); 57 return key; 58 } 59 } 60 } 61 62 private static class ReplaceBadChars extends ResourceKeyFormatter { 63 public String format(String key) { 64 return DEFAULT_CHARS.matcher(key).replaceAll("_"); 65 } 66 } 67 68 private abstract static class ResourceKeyFormatter { 69 public abstract String format(String key); 70 } 71 72 private static Pattern DEFAULT_CHARS = Pattern.compile("[.-]"); 73 74 77 protected SourceWriter composer; 78 79 private List formatters = new ArrayList (); 80 81 private File resourceFile; 82 83 private File sourceFile; 84 85 private PrintWriter writer; 86 87 96 public AbstractLocalizableInterfaceCreator(String className, 97 String packageName, File resourceBundle, File targetLocation, 98 Class interfaceClass) throws IOException { 99 setup(packageName, className, resourceBundle, targetLocation, 100 interfaceClass); 101 } 102 103 109 public void generate() throws FileNotFoundException , IOException { 110 try { 111 try { 112 generateFromPropertiesFile(); 114 } finally { 115 writer.close(); 116 } 117 } catch (IOException e) { 118 sourceFile.delete(); 119 throw e; 120 } catch (RuntimeException e) { 121 sourceFile.delete(); 122 throw e; 123 } 124 } 125 126 132 public void genSimpleMethodDecl(String key, String defaultValue) { 133 genMethodDecl("String", defaultValue, key, key); 134 } 135 136 141 protected abstract void genMethodArgs(String defaultValue); 142 143 149 protected abstract String javaDocComment(String path); 150 151 void generateFromPropertiesFile() throws IOException { 152 InputStream propStream = new FileInputStream (resourceFile); 153 LocalizedProperties p = new LocalizedProperties(); 154 p.load(propStream, Util.DEFAULT_ENCODING); 155 addFormatters(); 156 Iterator elements = p.getPropertyMap().entrySet().iterator(); 157 if (elements.hasNext() == false) { 158 throw new IllegalStateException ( 159 "File '" 160 + resourceFile 161 + "' cannot be used to generate message classes, as it has no key/value pairs defined."); 162 } 163 while (elements.hasNext()) { 164 Entry s = (Entry) elements.next(); 165 genSimpleMethodDecl((String ) s.getKey(), (String ) s.getValue()); 166 } 167 composer.commit(new PrintWriterTreeLogger()); 168 } 169 170 private void addFormatters() { 171 formatters.add(new ReplaceBadChars()); 173 174 formatters.add(new RenameDuplicates()); 176 } 177 178 private String formatKey(String key) { 179 for (int i = 0; i < formatters.size(); i++) { 180 ResourceKeyFormatter formatter = (ResourceKeyFormatter) formatters.get(i); 181 key = formatter.format(key); 182 } 183 if (Util.isValidJavaIdent(key) == false) { 184 System.err.println("Warning: " + key 185 + " is not a legitimate method name. " + sourceFile 186 + " will have compiler errors"); 187 } 188 return key; 189 } 190 191 private void genMethodDecl(String type, String defaultValue, String key, 192 String typeArg) { 193 composer.beginJavaDocComment(); 194 composer.println("Translated \"" + defaultValue + "\".\n"); 195 composer.println("@return translated \"" + defaultValue + "\""); 196 composer.print(I18NSync.ID + typeArg); 197 composer.endJavaDocComment(); 198 key = formatKey(key); 199 composer.print(type + " " + key); 200 composer.print("("); 201 genMethodArgs(defaultValue); 202 composer.print(");\n"); 203 } 204 205 private void setup(String packageName, String className, File resourceBundle, 206 File targetLocation, Class interfaceClass) throws IOException { 207 ClassSourceFileComposerFactory factory = new ClassSourceFileComposerFactory( 208 packageName, className); 209 factory.makeInterface(); 210 factory.setJavaDocCommentForClass(javaDocComment(resourceBundle.getCanonicalPath().replace( 211 File.separatorChar, '/'))); 212 factory.addImplementedInterface(interfaceClass.getName()); 213 FileOutputStream file = new FileOutputStream (targetLocation); 214 Writer underlying = new OutputStreamWriter (file, Util.DEFAULT_ENCODING); 215 writer = new PrintWriter (underlying); 216 composer = factory.createSourceWriter(writer); 217 resourceFile = resourceBundle; 218 sourceFile = targetLocation; 219 } 220 } 221 | Popular Tags |