1 4 5 9 10 package org.openlaszlo.sc; 11 import java.io.*; 12 import java.util.*; 13 import org.openlaszlo.server.LPS; 14 import org.openlaszlo.utils.ChainedException; 15 import org.openlaszlo.iv.flash.api.*; 16 import org.openlaszlo.iv.flash.api.action.*; 17 import org.openlaszlo.iv.flash.util.*; 18 import org.apache.log4j.*; 19 import org.openlaszlo.cache.Cache; 20 import org.openlaszlo.utils.FileUtils; 21 import org.openlaszlo.compiler.CompilationError; 22 23 29 public class ScriptCompiler extends Cache { 30 private static Logger mLogger = Logger.getLogger(ScriptCompiler.class); 31 32 static public final String SCRIPT_CACHE_NAME = "scache"; 33 34 37 private static ScriptCompiler mScriptCache = null; 40 41 public ScriptCompiler(String name, File cacheDirectory, Properties props) 42 throws IOException { 43 super(name, cacheDirectory, props); 44 } 45 46 public static ScriptCompiler getScriptCompilerCache() { 47 return mScriptCache; 48 } 49 50 public static synchronized ScriptCompiler initScriptCompilerCache(File cacheDirectory, Properties initprops) 51 throws IOException { 52 if (mScriptCache != null) { 53 return mScriptCache; 54 } 55 mScriptCache = new ScriptCompiler(SCRIPT_CACHE_NAME, cacheDirectory, initprops); 56 return mScriptCache; 57 } 58 59 66 public static void compile(String script, File outfile, int swfversion) 67 throws IOException 68 { 69 FileOutputStream ostream = new FileOutputStream(outfile); 70 compile(script, ostream, swfversion); 71 ostream.close(); 72 } 73 74 81 public static void compile(String script, OutputStream ostream, int swfversion) 82 throws IOException 83 { 84 byte[] action = compileToByteArray(script, new Properties()); 85 writeScriptToStream(action, ostream, swfversion); 86 } 87 88 95 public static boolean clearCacheStatic() { 96 if (mScriptCache != null) { 97 return mScriptCache.clearCache(); 98 } 99 return false; 100 } 101 102 103 private static byte[] _compileToByteArray(String script, 104 Properties properties) { 105 org.openlaszlo.sc.Compiler compiler = 106 new org.openlaszlo.sc.Compiler(); 107 compiler.setProperties(properties); 108 try { 109 return compiler.compile(script); 110 } catch (org.openlaszlo.sc.parser.TokenMgrError e) { 111 throw new CompilerException("Lexical error. The source location is for the element that contains the erroneous script. The error may come from an unterminated comment."); 115 } 116 } 117 118 121 static String sortedPropertiesList(Properties props) { 122 TreeSet sorted = new TreeSet (); 123 for (java.util.Enumeration e = props.propertyNames(); 124 e.hasMoreElements(); ) { 125 String key = (String ) e.nextElement(); 126 127 String value = props.getProperty(key); 128 StringBuffer buf = new StringBuffer (); 129 buf.append(key); 130 buf.append(' '); 131 buf.append(value); 132 133 sorted.add(buf.toString()); 134 } 135 StringBuffer buf = new StringBuffer (); 136 for (java.util.Iterator e = sorted.iterator(); e.hasNext(); ) { 137 String str = (String ) e.next(); 138 buf.append(str); 139 } 140 String propstring = buf.toString(); 141 return propstring; 142 } 143 144 145 146 151 public static byte[] compileToByteArray(String script, 152 Properties properties) { 153 mLogger.debug(script); 154 properties = (Properties) properties.clone(); 159 properties.setProperty("filename", ""); 160 StringWriter writer = new StringWriter(); 163 writer.write(sortedPropertiesList(properties)); 164 writer.getBuffer().append(script); 165 String key = writer.toString(); 166 ScriptCompiler cache = mScriptCache; 170 Item item = null; 171 byte[] code = null; 172 try { 173 if (mScriptCache == null) { 174 return _compileToByteArray(script, properties); 175 } else { 176 synchronized (mScriptCache) { 177 item = mScriptCache.findItem(key, null, false); 178 } 179 } 180 181 if (item.getInfo().getSize() != 0) { 182 code = item.getRawByteArray(); 183 } else { 184 code = _compileToByteArray(script, properties); 185 synchronized (mScriptCache) { 188 item.update(new ByteArrayInputStream(code), null); 189 item.updateInfo(); 190 item.markClean(); 191 } 192 } 193 194 mScriptCache.updateCache(item); 195 196 return (byte[]) code; 197 } catch (IOException e) { 198 throw new CompilationError(e, "IOException in compilation/script-cache"); 199 } 200 } 201 202 206 public static void writeScriptToStream(byte[] action, 207 OutputStream ostream, int swfversion) throws IOException { 208 FlashFile file = FlashFile.newFlashFile(); 209 Script s = new Script(1); 210 file.setMainScript(s); 211 file.setVersion(swfversion); 212 Program program = new Program(action, 0, action.length); 213 Frame frame = s.newFrame(); 214 frame.addFlashObject(new DoAction(program)); 215 InputStream input; 216 try { 217 input = file.generate().getInputStream(); 218 } 219 catch (IVException e) { 220 throw new ChainedException(e); 221 } 222 223 byte[] buffer = new byte[1024]; 224 int b = 0; 225 while((b = input.read(buffer)) > 0) { 226 ostream.write(buffer, 0, b); 227 } 228 } 229 230 231 232 239 public static void writeObject(Object object, java.io.Writer writer) 240 throws java.io.IOException 241 { 242 if (object instanceof Map) { 243 writeMap((Map) object, writer); 244 } else if (object instanceof List) { 245 writeList((List) object, writer); 246 } else { 247 writer.write(object.toString()); 248 } 249 } 250 251 264 private static void writeMap(Map map, java.io.Writer writer) 265 throws java.io.IOException 266 { 267 writer.write("{"); 268 SortedMap smap = new TreeMap(map); 271 for (Iterator iter = smap.entrySet().iterator(); iter.hasNext(); ) { 272 Map.Entry entry = (Map.Entry) iter.next(); 273 String key = (String ) entry.getKey(); 274 Object value = entry.getValue(); 275 if (!isIdentifier(key)) 276 key = quote(key); 277 writer.write(key + ": "); 278 writeObject(value, writer); 279 if (iter.hasNext()) { 280 writer.write(", "); 281 } 282 } 283 writer.write("}"); 284 } 285 286 299 private static void writeList(List list, java.io.Writer writer) 300 throws java.io.IOException 301 { 302 writer.write("["); 303 for (java.util.Iterator iter = list.iterator(); 304 iter.hasNext(); ) { 305 writeObject(iter.next(), writer); 306 if (iter.hasNext()) { 307 writer.write(", "); 308 } 309 } 310 writer.write("]"); 311 } 312 313 314 public static boolean isIdentifier(String s) { 315 if (s.length() == 0) 316 return false; 317 if (!Character.isJavaIdentifierStart(s.charAt(0))) 318 return false; 319 for (int i = 1; i < s.length(); i++) 320 if (!Character.isJavaIdentifierPart(s.charAt(i))) 321 return false; 322 s = s.intern(); 323 String [] keywords = {"break", "continue", "delete", "else", "for", "function", "if", "in", "instanceof", "new", "return", "this", "typeof", "var", "void", "while", "with", "case", "catch", "class", "const", "debugger", "default", "do", "enum", "export", "extends", "finally", "import", "super", "switch", "throw", "try"}; 324 for (int i = 0; i < keywords.length; i++) { 325 if (s == keywords[i]) 326 return false; 327 } 328 return true; 329 } 330 331 336 public static String quote(String s) { 337 try { 338 final char CHAR_ESCAPE = '\\'; 339 java.io.StringReader reader = new java.io.StringReader (s); 340 java.io.StringWriter writer = new java.io.StringWriter (); 341 writer.write('\"'); 342 int i; 343 while ((i = reader.read()) != -1) { 344 char c = (char) i; 345 switch (c) { 346 case '\n': 348 writer.write("\\n"); 349 break; 350 case '\r': 351 writer.write("\\r"); 352 break; 353 case '\\': 354 case '\"': 355 writer.write(CHAR_ESCAPE); 357 writer.write(c); 358 break; 359 default: 360 if (i < 32 || i >= 256) { 361 365 writer.write(CHAR_ESCAPE); 367 writer.write('u'); 368 writer.write(hexchar((c >> 12) & 0x0F)); 370 writer.write(hexchar((c >> 8) & 0x0F)); 371 writer.write(hexchar((c >> 4) & 0x0F)); 372 writer.write(hexchar(c & 0x0F)); 373 } else { 374 writer.write(c); 375 } 376 } 377 } 378 writer.write('\"'); 379 return writer.toString(); 380 } catch (java.io.IOException e) { 381 throw new ChainedException(e); 382 } 383 } 384 385 static char hexchar (int c) { 386 char hexchars[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; 387 return (hexchars[c & 0x0F]); 388 } 389 } 390 | Popular Tags |