1 16 package com.google.gwt.dev.util; 17 18 import com.google.gwt.dev.cfg.ModuleDef; 19 import com.google.gwt.dev.cfg.Properties; 20 import com.google.gwt.dev.cfg.Property; 21 import com.google.gwt.dev.cfg.PropertyProvider; 22 import com.google.gwt.dev.cfg.Script; 23 import com.google.gwt.dev.cfg.Scripts; 24 import com.google.gwt.dev.cfg.Styles; 25 import com.google.gwt.dev.js.JsObfuscateNamer; 26 import com.google.gwt.dev.js.JsParser; 27 import com.google.gwt.dev.js.JsParserException; 28 import com.google.gwt.dev.js.JsSourceGenerationVisitor; 29 import com.google.gwt.dev.js.JsSymbolResolver; 30 import com.google.gwt.dev.js.JsVerboseNamer; 31 import com.google.gwt.dev.js.ast.JsName; 32 import com.google.gwt.dev.js.ast.JsProgram; 33 import com.google.gwt.dev.js.ast.JsScope; 34 import com.google.gwt.util.tools.Utility; 35 36 import java.io.IOException ; 37 import java.io.PrintWriter ; 38 import java.io.Reader ; 39 import java.io.StringReader ; 40 import java.io.StringWriter ; 41 import java.net.MalformedURLException ; 42 import java.net.URL ; 43 import java.util.HashSet ; 44 import java.util.Iterator ; 45 import java.util.Map ; 46 import java.util.Set ; 47 import java.util.TreeMap ; 48 import java.util.Map.Entry; 49 50 56 public class SelectionScriptGenerator { 57 58 private static String cssInjector(String cssUrl) { 59 if (isRelativeURL(cssUrl)) { 60 return " if (!__gwt_stylesLoaded['" 61 + cssUrl 62 + "']) {\n" 63 + " __gwt_stylesLoaded['" 64 + cssUrl 65 + "'] = true;\n" 66 + " document.write('<link rel=\\\"stylesheet\\\" HREF=\\\"'+base+'" 67 + cssUrl + "\\\">');\n" + " }\n"; 68 } else { 69 return " if (!__gwt_stylesLoaded['" + cssUrl + "']) {\n" 70 + " __gwt_stylesLoaded['" + cssUrl + "'] = true;\n" 71 + " document.write('<link rel=\\\"stylesheet\\\" HREF=\\\"" 72 + cssUrl + "\\\">');\n" + " }\n"; 73 } 74 } 75 76 83 private static boolean isRelativeURL(String src) { 84 if (src.startsWith("/")) { 86 return false; 87 } 88 89 try { 91 URL testUrl = new URL (src); 92 93 return false; 95 } catch (MalformedURLException e) { 96 } 98 99 return true; 101 } 102 103 private static String literal(String lit) { 104 return "\"" + lit + "\""; 105 } 106 107 private static void replaceAll(StringBuffer buf, String search, String replace) { 108 int len = search.length(); 109 for (int pos = buf.indexOf(search); pos >= 0; pos = buf.indexOf(search, 110 pos + 1)) { 111 buf.replace(pos, pos + len, replace); 112 } 113 } 114 115 private static String scriptInjector(String scriptUrl) { 116 if (isRelativeURL(scriptUrl)) { 117 return " if (!__gwt_scriptsLoaded['" 118 + scriptUrl 119 + "']) {\n" 120 + " __gwt_scriptsLoaded['" 121 + scriptUrl 122 + "'] = true;\n" 123 + " document.write('<script language=\\\"javascript\\\" SRC=\\\"'+base+'" 124 + scriptUrl + "\\\"></script>');\n" + " }\n"; 125 } else { 126 return " if (!__gwt_scriptsLoaded['" + scriptUrl + "']) {\n" 127 + " __gwt_scriptsLoaded['" + scriptUrl + "'] = true;\n" 128 + " document.write('<script language=\\\"javascript\\\" SRC=\\\"" 129 + scriptUrl + "\\\"></script>');\n" + " }\n"; 130 } 131 } 132 133 private final String moduleFunction; 134 private final String moduleName; 135 private final Properties moduleProps; 136 private final Property[] orderedProps; 137 138 143 private final Map propertyValuesSetByStrongName = new TreeMap (); 144 private final Scripts scripts; 145 private final Styles styles; 146 147 154 public SelectionScriptGenerator(ModuleDef moduleDef) { 155 this.moduleName = moduleDef.getName(); 156 this.moduleFunction = moduleDef.getFunctionName(); 157 this.scripts = moduleDef.getScripts(); 158 this.styles = moduleDef.getStyles(); 159 this.moduleProps = moduleDef.getProperties(); 160 this.orderedProps = null; 161 } 162 163 173 public SelectionScriptGenerator(ModuleDef moduleDef, Property[] props) { 174 this.moduleName = moduleDef.getName(); 175 this.moduleFunction = moduleName.replace('.', '_'); 176 this.scripts = moduleDef.getScripts(); 177 this.styles = moduleDef.getStyles(); 178 this.moduleProps = moduleDef.getProperties(); 179 this.orderedProps = (Property[]) props.clone(); 180 } 181 182 187 public String generateSelectionScript(boolean obfuscate, boolean asScript) { 188 try { 189 String rawSource; 190 { 191 StringWriter sw = new StringWriter (); 192 PrintWriter pw = new PrintWriter (sw, true); 193 194 String template = Utility.getFileFromClassPath(asScript 195 ? "com/google/gwt/dev/util/SelectionScriptTemplate-xs.js" 196 : "com/google/gwt/dev/util/SelectionScriptTemplate.js"); 197 genScript(pw, template); 198 199 pw.close(); 200 rawSource = sw.toString(); 201 } 202 203 { 204 JsParser parser = new JsParser(); 205 Reader r = new StringReader (rawSource); 206 JsProgram jsProgram = new JsProgram(); 207 JsScope topScope = jsProgram.getScope(); 208 JsName funcName = topScope.declareName(moduleFunction); 209 funcName.setObfuscatable(false); 210 211 parser.parseInto(topScope, jsProgram.getGlobalBlock(), r, 1); 212 JsSymbolResolver.exec(jsProgram); 213 if (obfuscate) { 214 JsObfuscateNamer.exec(jsProgram); 215 } else { 216 JsVerboseNamer.exec(jsProgram); 217 } 218 219 DefaultTextOutput out = new DefaultTextOutput(obfuscate); 220 JsSourceGenerationVisitor v = new JsSourceGenerationVisitor(out); 221 v.accept(jsProgram); 222 return out.toString(); 223 } 224 } catch (IOException e) { 225 throw new RuntimeException ("Error processing selection script template.", 226 e); 227 } catch (JsParserException e) { 228 throw new RuntimeException ("Error processing selection script template.", 229 e); 230 } 231 } 232 233 242 public void recordSelection(String [] values, String strongName) { 243 Set valuesSet = (Set ) propertyValuesSetByStrongName.get(strongName); 244 if (valuesSet == null) { 245 valuesSet = new HashSet (); 246 propertyValuesSetByStrongName.put(strongName, valuesSet); 247 } 248 valuesSet.add(values.clone()); 249 } 250 251 private void genAnswers(PrintWriter pw) { 252 for (Iterator iter = propertyValuesSetByStrongName.entrySet().iterator(); iter.hasNext();) { 253 Map.Entry entry = (Entry) iter.next(); 254 String strongName = (String ) entry.getKey(); 255 Set propValuesSet = (Set ) entry.getValue(); 256 257 for (Iterator iterator = propValuesSet.iterator(); iterator.hasNext();) { 260 String [] propValues = (String []) iterator.next(); 261 262 pw.print(" unflattenKeylistIntoAnswers(["); 263 boolean firstPrint = true; 264 for (int i = 0; i < orderedProps.length; i++) { 265 Property prop = orderedProps[i]; 266 String activeValue = prop.getActiveValue(); 267 if (activeValue == null) { 268 if (!firstPrint) { 272 pw.print(","); 273 } 274 firstPrint = false; 275 pw.print(literal(propValues[i])); 276 } else { 277 } 280 } 281 pw.print("]"); 282 pw.print(","); 283 pw.print(literal(strongName)); 284 pw.println(");"); 285 } 286 } 287 } 288 289 private void genPropProviders(PrintWriter pw) { 290 for (Iterator iter = moduleProps.iterator(); iter.hasNext();) { 291 Property prop = (Property) iter.next(); 292 String activeValue = prop.getActiveValue(); 293 if (activeValue == null) { 294 PropertyProvider provider = prop.getProvider(); 296 assert (provider != null) : "expecting a default property provider to have been set"; 297 String js = provider.getBody().toSource(); 298 pw.print("providers['" + prop.getName() + "'] = function() "); 299 pw.print(js); 300 pw.println(";"); 301 302 pw.println(); 304 pw.println("values['" + prop.getName() + "'] = {"); 305 String [] knownValues = prop.getKnownValues(); 306 for (int i = 0; i < knownValues.length; i++) { 307 if (i > 0) { 308 pw.println(", "); 309 } 310 pw.print(literal(knownValues[i]) + ": "); 315 pw.print(i); 316 } 317 pw.println(); 318 pw.println("};"); 319 } 320 } 321 } 322 323 private void genPropValues(PrintWriter pw) { 324 for (int i = 0; i < orderedProps.length; i++) { 325 Property prop = orderedProps[i]; 326 String activeValue = prop.getActiveValue(); 327 if (activeValue == null) { 328 PropertyProvider provider = prop.getProvider(); 332 assert (provider != null) : "expecting a default property provider to have been set"; 333 pw.print("["); 337 pw.print("computePropValue('" + prop.getName() + "')"); 338 pw.print("]"); 339 } else { 340 } 342 } 343 } 344 345 351 private void genScript(PrintWriter mainPw, String template) { 352 StringBuffer buf = new StringBuffer (template); 353 replaceAll(buf, "__MODULE_FUNC__", moduleFunction); 354 replaceAll(buf, "__MODULE_NAME__", moduleName); 355 356 if (orderedProps != null) { 357 int startPos = buf.indexOf("// __SHELL_SERVLET_ONLY_BEGIN__"); 359 int endPos = buf.indexOf("// __SHELL_SERVLET_ONLY_END__"); 360 buf.delete(startPos, endPos); 361 } 362 363 int startPos = buf.indexOf("// __MODULE_DEPS_END__"); 365 for (Iterator iter = styles.iterator(); iter.hasNext();) { 366 String style = (String ) iter.next(); 367 String text = cssInjector(style); 368 buf.insert(startPos, text); 369 startPos += text.length(); 370 } 371 372 for (Iterator iter = scripts.iterator(); iter.hasNext();) { 373 Script script = (Script) iter.next(); 374 String text = scriptInjector(script.getSrc()); 375 buf.insert(startPos, text); 376 startPos += text.length(); 377 } 378 379 { 381 StringWriter sw = new StringWriter (); 382 PrintWriter pw = new PrintWriter (sw, true); 383 genPropProviders(pw); 384 pw.close(); 385 String stuff = sw.toString(); 386 startPos = buf.indexOf("// __PROPERTIES_END__"); 387 buf.insert(startPos, stuff); 388 } 389 390 { 392 StringWriter sw = new StringWriter (); 393 PrintWriter pw = new PrintWriter (sw, true); 394 395 if (orderedProps != null) { 398 if (propertyValuesSetByStrongName.size() > 1) { 400 pw.println(); 402 genAnswers(pw); 403 pw.println(); 404 pw.print(" strongName = answers"); 405 genPropValues(pw); 406 } else { 407 Set entrySet = propertyValuesSetByStrongName.entrySet(); 409 assert (entrySet.size() == 1); 410 Map.Entry entry = (Entry) entrySet.iterator().next(); 411 String strongName = (String ) entry.getKey(); 412 pw.print(" strongName = " + literal(strongName)); 414 } 415 pw.println(";"); 416 } 417 418 pw.close(); 419 String stuff = sw.toString(); 420 startPos = buf.indexOf("// __PERMUTATIONS_END__"); 421 buf.insert(startPos, stuff); 422 } 423 424 mainPw.print(buf.toString()); 425 } 426 427 } 428 | Popular Tags |