001: /* -*- mode: Java; c-basic-offset: 2; -*- */
002:
003: /**
004: * Library output
005: *
006: * @author ptw@openlaszlo.org
007: *
008: * Outputs schema and script for a library
009: */package org.openlaszlo.compiler;
010:
011: import java.io.*;
012: import java.net.*;
013: import java.util.*;
014:
015: import org.jdom.Element;
016:
017: import org.openlaszlo.sc.ScriptCompiler;
018: import org.openlaszlo.sc.JavascriptCompressor;
019: import org.openlaszlo.utils.*;
020:
021: /** Accumulates code, XML, and assets to a Library object file.
022: *
023: * Properties documented in Compiler.getProperties.
024: */
025: class LibraryWriter extends DHTMLWriter {
026:
027: PrintStream out;
028: Element root;
029:
030: LibraryWriter(Properties props, OutputStream stream,
031: CompilerMediaCache cache, boolean importLibrary,
032: CompilationEnvironment env, Element root) {
033: super (props, stream, cache, importLibrary, env);
034:
035: try {
036: this .out = new PrintStream(
037: new java.util.zip.GZIPOutputStream(mStream));
038: } catch (Exception e) {
039: throw new ChainedException(e);
040: }
041: this .root = root;
042: }
043:
044: /**
045: * Sets the canvas for the app
046: *
047: * @param canvas
048: *
049: */
050: // TODO: [[2007-01-30 ptw] This should become an error
051: void setCanvas(Canvas canvas, String canvasConstructor) {
052: }
053:
054: private Map resourceMap = new TreeMap();
055:
056: /** Import a resource file into the current movie.
057: * Using a name that already exists clobbers the
058: * old resource (for now).
059: *
060: * @param fileName file name of the resource
061: * @param name name of the MovieClip/Sprite
062: * @throws CompilationError
063: */
064: public void importResource(String fileName, String name)
065: throws ImportResourceError {
066: resourceMap.put(name, fileName);
067: }
068:
069: public void importResource(File inputFile, String name)
070: throws ImportResourceError {
071: importResource(inputFile.toString(), name);
072: }
073:
074: public void importResource(List sources, String name, File parent) {
075: resourceMap.put(name, sources);
076: }
077:
078: private String adjustResourcePath(String src) {
079: try {
080: return new URL(src).toString();
081: } catch (MalformedURLException e) {
082: try {
083: String outdir = FileUtils.toURLPath(mEnv
084: .getObjectFile().getCanonicalFile()
085: .getParentFile());
086: File file = new File(src).getCanonicalFile();
087: return FileUtils.adjustRelativePath(file.getName(),
088: outdir, FileUtils.toURLPath(file
089: .getParentFile()));
090: } catch (IOException f) {
091: return src;
092: }
093: }
094: }
095:
096: private void exportAttributes() {
097: }
098:
099: private void exportResources() {
100: for (Iterator i = resourceMap.entrySet().iterator(); i
101: .hasNext();) {
102: Map.Entry entry = (Map.Entry) i.next();
103: Object value = entry.getValue();
104: if (value instanceof List) {
105: out.println("<resource name='" + entry.getKey() + "'>");
106: for (Iterator j = ((List) value).iterator(); j
107: .hasNext();) {
108: // Make relative to lib
109: String src = adjustResourcePath((String) j.next());
110: out.println(" <frame src='" + src + "' />");
111: }
112: out.println("</resource>");
113: } else {
114: // Make relative to lib
115: String src = adjustResourcePath((String) value);
116: out.println("<resource name='" + entry.getKey()
117: + "' src='" + src + "' />");
118: }
119: }
120: }
121:
122: private void exportInterface() {
123: out.println(mEnv.getSchema().toLZX());
124: }
125:
126: private void exportScript() {
127: out
128: .println("<script when='immediate' type='LZBinary'>\n<![CDATA[\n");
129: // Write 'compressed' output
130: org.openlaszlo.sc.parser.SimpleNode program = (new org.openlaszlo.sc.Compiler.Parser())
131: .parse(scriptBuffer.toString());
132: JavascriptCompressor compressor = new JavascriptCompressor();
133: program = compressor.compress(program);
134: boolean compress = (!mEnv.getProperty(
135: org.openlaszlo.sc.Compiler.NAME_FUNCTIONS, "false")
136: .equals("true"));
137: boolean obfuscate = compress
138: || mEnv.getProperty(
139: org.openlaszlo.sc.Compiler.OBFUSCATE, "false")
140: .equals("true");
141: (new org.openlaszlo.sc.ParseTreePrinter(compress, obfuscate))
142: .print(program, out);
143: out.println("\n]]>\n</script>");
144: }
145:
146: // Must preserve visited order for output of includes
147: private Map autoIncludes = new LinkedHashMap();
148: private Map includes = new LinkedHashMap();
149:
150: private String libraries() {
151: StringWriter writer = new StringWriter();
152: PrintWriter out = new PrintWriter(writer);
153: String indent = "";
154: for (Iterator i = includes.keySet().iterator(); i.hasNext();) {
155: File library = (File) i.next();
156: if (!autoIncludes.containsKey(library)) {
157: String path = adjustResourcePath(library.getPath());
158: out.println(indent + path);
159: indent = " ";
160: }
161: }
162: String result = writer.toString();
163: if (result.length() > 0) {
164: return " includes=\""
165: + result.substring(0, result.length() - 1) + "\"";
166: }
167: return "";
168: }
169:
170: private void exportIncludes() {
171: Set implicit = new HashSet();
172: for (Iterator i = autoIncludes.keySet().iterator(); i.hasNext();) {
173: File key = (File) i.next();
174: if (!implicit.contains(key)) {
175: Set subIncludes = (Set) autoIncludes.get(key);
176: if (subIncludes != null) {
177: // An auto-include will not have been parsed for sub-includes?
178: implicit.addAll(subIncludes);
179: }
180: String path = adjustResourcePath(key.getPath());
181: out.println("<include href='" + path + "' />");
182: }
183: }
184: }
185:
186: public void close() throws IOException {
187: //Should we emit javascript or SWF?
188: //boolean emitScript = mEnv.isLibrary();
189:
190: if (mCloseCalled) {
191: throw new IllegalStateException(
192: "LibraryWriter.close() called twice");
193: }
194:
195: try {
196: Properties props = (Properties) mProperties.clone();
197:
198: ToplevelCompiler.getLibraries(mEnv, root, null,
199: autoIncludes, includes);
200:
201: out
202: .println("<!-- This is a binary library. Not meant for human consumption. -->");
203: out
204: .println("<!-- DO NOT EDIT THIS FILE. Edit the source and recompile with `-c` -->");
205: out.println("<library" + libraries() + ">");
206: exportAttributes();
207: exportIncludes();
208: exportInterface();
209: exportResources();
210: exportScript();
211: out.println("</library>");
212:
213: } catch (Exception e) {
214: throw new ChainedException(e);
215: } finally {
216: out.close();
217: }
218:
219: mCloseCalled = true;
220: }
221:
222: }
223:
224: /**
225: * @copyright Copyright 2007 Laszlo Systems, Inc. All Rights
226: * Reserved. Use is subject to license terms.
227: */
|