Source Code Cross Referenced for CompilationManager.java in  » Ajax » Laszlo-4.0.10 » org » openlaszlo » cm » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Ajax » Laszlo 4.0.10 » org.openlaszlo.cm 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* *****************************************************************************
002:         * CompilationManager.java
003:         * ****************************************************************************/
004:
005:        /* J_LZ_COPYRIGHT_BEGIN *******************************************************
006:         * Copyright 2001-2007 Laszlo Systems, Inc.  All Rights Reserved.              *
007:         * Use is subject to license terms.                                            *
008:         * J_LZ_COPYRIGHT_END *********************************************************/
009:
010:        package org.openlaszlo.cm;
011:
012:        import java.io.InputStream;
013:        import java.io.File;
014:        import java.io.FileOutputStream;
015:        import java.io.FilterOutputStream;
016:        import java.io.FileInputStream;
017:        import java.io.PrintWriter;
018:        import java.io.FileNotFoundException;
019:        import java.io.IOException;
020:        import java.io.Serializable;
021:        import java.util.*;
022:        import org.openlaszlo.compiler.*;
023:        import org.openlaszlo.server.LPS;
024:        import org.openlaszlo.server.Configuration;
025:        import org.openlaszlo.utils.FileUtils;
026:        import org.openlaszlo.utils.LZHttpUtils;
027:        import org.openlaszlo.cache.Cache;
028:        import org.openlaszlo.compiler.CompilationEnvironment;
029:        import org.apache.log4j.*;
030:
031:        /** A <code>CompilationManager</code> is responsible for maintaining
032:         * the correspondence between source and object files.  It's
033:         * responsible for dependency analysis, caching, and selective recompilation.
034:         *
035:         * The main entry point to the Compilationmanager code is getObjectStream
036:         *
037:         * A CompilationManager is constructed with a source directory, where it
038:         * looks for source files, and a cache directory, where it places
039:         * compiled object files and cached (dependency) information.  It can be
040:         * instructed to always recompile files, never recompile them so long
041:         * as they exist, or use dependency information that it creates during
042:         * the course of a file compilation to determine whether a file is out
043:         * of date.  See the documentation for getProperty() for a description
044:         * of how to select between these behaviors.
045:         *
046:         * The compilation manager currently uses itself to represent the
047:         * cache, and methods that access the cache are synchronized.  This
048:         * would have to change to support multiple readers.
049:         *
050:         * Methods that trigger recompilation are synchronized: it's safe for
051:         * multiple threads to contain references to a compilation manager if
052:         * they are only using it to compile.  Accessor methods should only be
053:         * called single-threaded.  Two compilation managers shouldn't be
054:         * pointed at the same cache directory.
055:         */
056:        public class CompilationManager extends Cache {
057:            /** Logger. */
058:            private static Logger mLogger = Logger
059:                    .getLogger(CompilationManager.class);
060:
061:            /** See the constructor. */
062:            protected File mSourceDirectory;
063:            /** See the constructor. */
064:            protected File mCacheDirectory;
065:            /** Cache for compiled media */
066:            protected CompilerMediaCache mMediaCache;
067:            /** See getProperties. */
068:            protected Properties mProperties = null;
069:
070:            protected File mLPSJarFile = null;
071:
072:            private int[] lfcsizes = null;
073:
074:            public static final String RECOMPILE = "lzrecompile";
075:
076:            /**
077:             * Creates a new <code>CompilationManager</code> instance.
078:             *
079:             * @param sourceDirectory a <code>File</code> naming a directory,
080:             * that is used as a base for resolving relative names that are
081:             * passed to getObjectData.
082:             *
083:             * @param cacheDirectory a <code>File</code> naming a directory.
084:             * The <code>CompilationManager</code> places object files and
085:             * dependency-tracking information here, to avoid unnecessary
086:             * subsequent recompilation.
087:             *
088:             */
089:            public CompilationManager(File sourceDirectory,
090:                    File cacheDirectory, Properties props) throws IOException {
091:                super ("cache", cacheDirectory, props);
092:                this .mSourceDirectory = sourceDirectory;
093:                this .mCacheDirectory = cacheDirectory;
094:                try {
095:                    cacheDirectory.mkdirs();
096:                } catch (SecurityException se) {
097:                }
098:                if (!cacheDirectory.exists()) {
099:                    throw new FileNotFoundException(
100:                    /* (non-Javadoc)
101:                     * @i18n.test
102:                     * @org-mes=p[0] + " does not exist"
103:                     */
104:                    org.openlaszlo.i18n.LaszloMessages.getMessage(
105:                            CompilationManager.class.getName(), "051018-102",
106:                            new Object[] { cacheDirectory.getAbsolutePath() }));
107:                }
108:                if (!cacheDirectory.canRead()) {
109:                    throw new IOException(
110:                    /* (non-Javadoc)
111:                     * @i18n.test
112:                     * @org-mes="can't read " + p[0]
113:                     */
114:                    org.openlaszlo.i18n.LaszloMessages.getMessage(
115:                            CompilationManager.class.getName(), "051018-112",
116:                            new Object[] { cacheDirectory.getAbsolutePath() }));
117:                }
118:                String p = cacheDirectory.getAbsolutePath() + File.separator
119:                        + "media";
120:                this .mMediaCache = new CompilerMediaCache(new File(p), props);
121:                this .mProperties = props;
122:
123:                String jd = LPS.getProperty("compMgr.lps.jar.dependency",
124:                        "true");
125:                if ("true".equals(jd)) {
126:                    mLPSJarFile = LPS.getLPSJarFile();
127:                }
128:            }
129:
130:            /** 
131:             * Returns the media cache for the compilation manager
132:             */
133:            public CompilerMediaCache getCompilerMediaCache() {
134:                return mMediaCache;
135:            }
136:
137:            /** Sets the source directory.  This is the directory within which
138:             * source files will be searched for.
139:             * @param sourceDirectory a File
140:             */
141:            public void setSourceDirectory(File sourceDirectory) {
142:                this .mSourceDirectory = sourceDirectory;
143:            }
144:
145:            /** Clear the cache. 
146:             * @return true if full removal of cache was successful, otherwise false.
147:             */
148:            public boolean clearCacheDirectory() {
149:                return mMediaCache.clearCache() && clearCache();
150:            }
151:
152:            /** Miscellaneous properties.
153:             *
154:             * <dl>
155:             * <dt>recompile=always
156:             * <dd>Always recompile object files, regardless of whether source
157:             * files have changed.
158:             * <dt>recompile=never
159:             * <dd>Never recompile object files.
160:             * <dt>recompile=check (default)
161:             * <dd>Recompile an object file if a source file that it depends
162:             * on has changed.
163:             * </dl>
164:             *
165:             * Additionally, if <code>getProperties().getProperty("compiler."
166:             * + <var>key</var>) == <var>value</var></code>, then files are
167:             * compiled with a compiler such that
168:             * <code>compiler.getProperty(<var>key</var>) ==
169:             * <var>value</var></code>.
170:             * @return a Properties
171:             */
172:            public Properties getProperties() {
173:                return mProperties;
174:            }
175:
176:            public void setProperty(String key, String value) {
177:                mProperties.setProperty(key, value);
178:            }
179:
180:            protected void afterCacheRead(Object metaData) {
181:                CachedInfo ci = (CachedInfo) metaData;
182:                DependencyTracker dt = ci.getDependencyTracker();
183:
184:                // update webapp path of cache files
185:                dt.updateWebappPath();
186:
187:                // set application options in configuration
188:                Canvas canvas = ci.getCanvas();
189:                LPS.configuration.setApplicationOptions(canvas.getFilePath(),
190:                        canvas.getSecurityOptions());
191:            }
192:
193:            /**
194:             * Returns a File containing the compiled form of the file 
195:             * named by pathname, suitable play on the client.  
196:             *
197:             * @param pathname a <code>String</code> value.  If
198:             * <var>pathname</var> is relative, it is resolved relative to the
199:             * CompilationManager's <var>sourceDirectory</var>.
200:             * @param props params for dependency tracker and compiler
201:             * @return the compiled File object.
202:             * @exception CompilationError if an error occurs.
203:             */
204:            public synchronized File getObjectFile(String pathname,
205:                    Properties props) throws CompilationError, IOException {
206:                mLogger.debug(
207:                /* (non-Javadoc)
208:                 * @i18n.test
209:                 * @org-mes="getObjectFile for " + p[0]
210:                 */
211:                org.openlaszlo.i18n.LaszloMessages.getMessage(
212:                        CompilationManager.class.getName(), "051018-208",
213:                        new Object[] { pathname.toString() }));
214:                return getItem(pathname, props).getFile();
215:            }
216:
217:            /**
218:             * Returns an InputStream containing the compiled form of the file 
219:             * named by pathname, suitable play on the client.  
220:             *
221:             * @param pathname a <code>String</code> value.  If
222:             * <var>pathname</var> is relative, it is resolved relative to the
223:             * CompilationManager's <var>sourceDirectory</var>.
224:             * @param props params for dependency tracker and compiler
225:             * @return the compiled File object.
226:             * @exception CompilationError if an error occurs.
227:             */
228:            public synchronized InputStream getObjectStream(String pathname,
229:                    Properties props) throws CompilationError, IOException {
230:                return getItem(pathname, props).getStream();
231:            }
232:
233:            /**
234:             * Returns an InputStream containing the script form of the file 
235:             * named by pathname, suitable play on the client.  
236:             *
237:             * @param pathname a <code>String</code> value.  If
238:             * <var>pathname</var> is relative, it is resolved relative to the
239:             * CompilationManager's <var>sourceDirectory</var>.
240:             * @param props params for dependency tracker and compiler
241:             * @return the compiled File object.
242:             * @exception CompilationError if an error occurs.
243:             */
244:            public synchronized InputStream getScriptStream(String pathname,
245:                    Properties props) throws CompilationError, IOException {
246:                return getItem(pathname, props).getStream();
247:            }
248:
249:            /**
250:             * @return the canvas for this app
251:             */
252:            public synchronized Canvas getCanvas(String pathname)
253:                    throws CompilationError, IOException {
254:                return getCanvas(pathname, new Properties());
255:            }
256:
257:            /**
258:             * Return the canvas associated with the given LZX file
259:             *
260:             * @return the canvas
261:             * @param pathname path to the LZX file
262:             * @param props props for dependency tracker and compiler
263:             * @throws CompilationError if there is a compilation error
264:             * in the file
265:             */
266:            public synchronized Canvas getCanvas(String pathname,
267:                    Properties props) throws CompilationError, IOException {
268:
269:                mLogger.debug(
270:                /* (non-Javadoc)
271:                 * @i18n.test
272:                 * @org-mes="getCanvas for " + p[0]
273:                 */
274:                org.openlaszlo.i18n.LaszloMessages.getMessage(
275:                        CompilationManager.class.getName(), "051018-469",
276:                        new Object[] { pathname.toString() }));
277:                CachedInfo info = (CachedInfo) getItem(pathname, props)
278:                        .getMetaData();
279:                return info.getCanvas();
280:            }
281:
282:            /**
283:             * @return an array with the size and gzipped size of the InputStream in 
284:             * bytes
285:             */
286:            private int[] getLFCSizes(InputStream in) throws IOException {
287:                java.io.ByteArrayOutputStream outbuf = new java.io.ByteArrayOutputStream();
288:                java.util.zip.GZIPOutputStream out = new java.util.zip.GZIPOutputStream(
289:                        outbuf);
290:                int size = FileUtils.sendToStream(in, out);
291:                in.close();
292:                out.finish();
293:                int gzsize = outbuf.size();
294:                out.close();
295:                int[] result = { size, gzsize };
296:                return result;
297:            }
298:
299:            /**
300:             * @return a String containing XML info about this app
301:             */
302:            public synchronized String getInfoXML(String pathname,
303:                    Properties props) throws CompilationError, IOException {
304:
305:                if (pathname == null) {
306:                    return "";
307:                }
308:
309:                Item item = getItem(pathname, props);
310:                String enc = props.getProperty(LZHttpUtils.CONTENT_ENCODING);
311:
312:                boolean isDebug = "true".equals(props.getProperty("debug"));
313:                boolean isProfile = "true".equals(props.getProperty("profile"));
314:                boolean isBacktrace = "true".equals(props
315:                        .getProperty("backtrace"));
316:                String runtime = props
317:                        .getProperty(CompilationEnvironment.RUNTIME_PROPERTY);
318:
319:                String lfc = LPS.getLFCname(runtime, isDebug, isProfile,
320:                        isBacktrace);
321:                String path = LPS.getLFCDirectory();
322:
323:                File lfcfile = new File(path, lfc);
324:
325:                // TODO: update to cache correct size for debug, profiled LFC
326:                if (lfcsizes == null)
327:                    lfcsizes = getLFCSizes(new FileInputStream(lfcfile));
328:                int lfcsize = lfcsizes[0];
329:                int gzlfcsize = lfcsizes[1];
330:
331:                int[] sizes = getLFCSizes(getObjectStream(pathname, props));
332:                int size = sizes[0];
333:                int gzsize = sizes[1];
334:
335:                boolean debugExists = isDebug;
336:                boolean nondebugExists = !isDebug;
337:                boolean debugUptodate = false;
338:                boolean nondebugUptodate = false;
339:                Properties alt = null;
340:
341:                if (isDebug) {
342:                    alt = (Properties) props.clone();
343:                    alt.setProperty("debug", "false");
344:                    nondebugExists = (getItem(computeKey(pathname, alt)) != null);
345:                } else {
346:                    alt = (Properties) props.clone();
347:                    alt.setProperty("debug", "true");
348:                    debugExists = (getItem(computeKey(pathname, alt)) != null);
349:                }
350:
351:                if (debugExists) {
352:                    Properties p;
353:                    if (!isDebug) {
354:                        item = getItem(computeKey(pathname, alt));
355:                        p = (Properties) alt.clone();
356:                    } else {
357:                        p = (Properties) props.clone();
358:                    }
359:                    CachedInfo info = (CachedInfo) item.getMetaData();
360:                    if (info != null) {
361:                        DependencyTracker tracker = info.getDependencyTracker();
362:                        debugUptodate = tracker.isUpToDate(p);
363:                    }
364:                }
365:
366:                if (nondebugExists) {
367:                    Properties p;
368:                    if (isDebug) {
369:                        item = getItem(computeKey(pathname, alt));
370:                        p = (Properties) alt.clone();
371:                    } else {
372:                        item = getItem(computeKey(pathname, props));
373:                        p = (Properties) props.clone();
374:                    }
375:                    CachedInfo info = (CachedInfo) item.getMetaData();
376:                    if (info != null) {
377:                        DependencyTracker tracker = info.getDependencyTracker();
378:                        nondebugUptodate = tracker.isUpToDate(p);
379:                    }
380:                }
381:
382:                return "<info size=\"" + size + "\" debug=\"" + isDebug
383:                        + "\" encoding=\"" + enc + "\" debug-exists=\""
384:                        + debugExists + "\" debug-up-to-date=\""
385:                        + debugUptodate + "\" nondebug-exists=\""
386:                        + nondebugExists + "\" nondebug-up-to-date=\""
387:                        + nondebugUptodate + "\" runtime=\"" + runtime
388:                        + "\" gzsize=\"" + gzsize + "\" lfcsize=\"" + lfcsize
389:                        + "\" gzlfcsize=\"" + gzlfcsize + "\" />";
390:            }
391:
392:            /**
393:             * Return the last modified time associated with the given LZX file
394:             *
395:             * @return the last modified time in utc
396:             * @param pathname path to the LZX file
397:             * @param props params for dependency tracker and compiler
398:             * @throws CompilationError if there is a compilation error
399:             * in the file
400:             */
401:            public synchronized long getLastModified(String pathname,
402:                    Properties props) throws CompilationError, IOException {
403:                mLogger.debug(
404:                /* (non-Javadoc)
405:                 * @i18n.test
406:                 * @org-mes="getLastModified for " + p[0]
407:                 */
408:                org.openlaszlo.i18n.LaszloMessages.getMessage(
409:                        CompilationManager.class.getName(), "051018-590",
410:                        new Object[] { pathname.toString() }));
411:                // This is the last modified time from the item in the cache
412:                File file = new File(getItem(pathname, props).getPathName());
413:                return file.lastModified();
414:            }
415:
416:            /**
417:             * Get the cached item.  Recompile or convert encoding as needed.
418:             *
419:             * @param pathname path to the LZX file
420:             * @param props params for compiler
421:             */
422:            public synchronized Item getItem(String pathname, Properties props)
423:                    throws IOException {
424:
425:                Serializable key = computeKey(pathname, props);
426:                String enc = props.getProperty(LZHttpUtils.CONTENT_ENCODING);
427:                boolean lockit = false;
428:                Item item = findItem(key, enc, lockit);
429:                // Set up the properties, for dependency checking
430:                Properties compilationProperties = (Properties) props.clone();
431:                if (!isItemUpToDate(item, pathname, compilationProperties)) {
432:
433:                    Properties props2 = (Properties) props.clone();
434:                    if (enc == null || enc.equals("")) {
435:                        props2
436:                                .setProperty(LZHttpUtils.CONTENT_ENCODING,
437:                                        "gzip");
438:                    } else {
439:                        props2.setProperty(LZHttpUtils.CONTENT_ENCODING, "");
440:                    }
441:                    Serializable key2 = computeKey(pathname, props2);
442:                    Item item2 = getItem(key2);
443:                    if (item2 != null
444:                            && isItemUpToDate(item2, pathname, props2)) {
445:                        convertItemEncoding(item2, item, pathname, enc,
446:                                compilationProperties);
447:                    } else {
448:                        compileItem(item, pathname, compilationProperties);
449:                    }
450:                }
451:                updateCache(item);
452:                return item;
453:            }
454:
455:            /**
456:             * Take source item, un-encode it, and then re-encode and store in dest item
457:             * with the specified encoding
458:             * @param src - source item
459:             * @param dest - dest item
460:             * @param pathname - pathname for destination item
461:             * @param enc - encoding for dest
462:             * @param props - properties for compile
463:             *
464:             * For now, hardcoded to only support gzip.
465:             */
466:            public synchronized void convertItemEncoding(Item src, Item dest,
467:                    String pathname, String enc, Properties props) {
468:
469:                File srcFile = src.getFile();
470:                File destFile = new File(dest.getPathName());
471:                CachedInfo srcInfo = (CachedInfo) src.getMetaData();
472:                try {
473:
474:                    dest.markDirty();
475:
476:                    File tempFile = null;
477:                    FileInputStream tempFileStream = null;
478:                    try {
479:                        tempFile = File.createTempFile("lzc-", null);
480:                        mLogger.debug(
481:                        /* (non-Javadoc)
482:                         * @i18n.test
483:                         * @org-mes="Temporary file is " + p[0]
484:                         */
485:                        org.openlaszlo.i18n.LaszloMessages.getMessage(
486:                                CompilationManager.class.getName(),
487:                                "051018-663", new Object[] { tempFile
488:                                        .getAbsolutePath() }));
489:
490:                        mLogger.debug(
491:                        /* (non-Javadoc)
492:                         * @i18n.test
493:                         * @org-mes="Re-encoding from " + p[0] + " to " + p[1]
494:                         */
495:                        org.openlaszlo.i18n.LaszloMessages.getMessage(
496:                                CompilationManager.class.getName(),
497:                                "051018-672",
498:                                new Object[] { srcFile.toString(),
499:                                        tempFile.toString() }));
500:
501:                        if (enc != null && enc.equals("gzip")) {
502:                            // Encode from uncompressed to gzip
503:                            FileUtils.encode(srcFile, tempFile, enc);
504:                        } else {
505:                            // Decode from gzip to uncompressed.
506:                            FileUtils.decode(srcFile, tempFile, "gzip");
507:                        }
508:
509:                        tempFileStream = new FileInputStream(tempFile);
510:
511:                        dest.update(tempFileStream);
512:
513:                        DependencyTracker dependencyTracker = new DependencyTracker(
514:                                props);
515:                        dependencyTracker.copyFiles(srcInfo
516:                                .getDependencyTracker(), srcFile);
517:                        dependencyTracker.addFile(destFile);
518:
519:                        // FIXME: [2003-07-21 bloch] the factoring of cm.CacheInfo and cache.CacheInfo
520:                        // has never been right.  Someday, if there are more subclasses of Cache that
521:                        // use the [gs]etMetaData methods, then this should really be fixed.  (bug #1778).
522:                        CachedInfo info = new CachedInfo(dependencyTracker,
523:                                srcInfo.getCanvas(), enc);
524:                        dest.getInfo().setLastModified(destFile.lastModified());
525:                        dest.update(info);
526:                        dest.markClean();
527:
528:                    } finally {
529:                        if (tempFileStream != null) {
530:                            FileUtils.close(tempFileStream);
531:                        }
532:                        if (tempFile != null) {
533:                            tempFile.delete();
534:                        }
535:                        // Cleanup now
536:                        mLogger.debug(
537:                        /* (non-Javadoc)
538:                         * @i18n.test
539:                         * @org-mes="starting gc"
540:                         */
541:                        org.openlaszlo.i18n.LaszloMessages.getMessage(
542:                                CompilationManager.class.getName(),
543:                                "051018-713"));
544:                        System.gc();
545:                        mLogger.debug(
546:                        /* (non-Javadoc)
547:                         * @i18n.test
548:                         * @org-mes="finished gc"
549:                         */
550:                        org.openlaszlo.i18n.LaszloMessages.getMessage(
551:                                CompilationManager.class.getName(),
552:                                "051018-722"));
553:                    }
554:
555:                } catch (IOException ioe) {
556:                    CompilationError e = new CompilationError(ioe);
557:                    e.initPathname(pathname);
558:                    throw e;
559:                }
560:            }
561:
562:            /**
563:             * @return true if the item is up to date
564:             *
565:             * @param pathname a <code>String</code> value.  If
566:             * <var>pathname</var> is relative, it is resolved relative to the
567:             * CompilationManager's <var>sourceDirectory</var>.
568:             * @param props properties that affect the compile.
569:             * @return the bytes of the object file
570:             * @exception CompilationError if an error occurs
571:             *
572:             * The PROPS parameter may contain 
573:             * <ul>
574:             * <li>"Content-Encoding" =&gt; the encoding of the output (ignore if null)
575:             * </ul>
576:             * NOTE: can remove the recompile property from props 
577:             */
578:            public boolean isItemUpToDate(Item item, String pathname,
579:                    Properties props) throws CompilationError {
580:
581:                File sourceFile = new File(mSourceDirectory, pathname);
582:                File objectFile = new File(item.getPathName());
583:
584:                boolean recompile = props.getProperty(RECOMPILE) != null;
585:                props.remove(RECOMPILE);
586:
587:                boolean upToDate = false;
588:
589:                try {
590:                    String recompileSwitch = mProperties.getProperty(
591:                            "recompile", "check").intern();
592:
593:                    if (pathname.endsWith(".lzo")) {
594:                        return true; // we cannot recompile a kranked file automatically
595:                    } else if (recompile) {
596:                        mLogger.info(
597:                        /* (non-Javadoc)
598:                         * @i18n.test
599:                         * @org-mes="forcing a recompile"
600:                         */
601:                        org.openlaszlo.i18n.LaszloMessages.getMessage(
602:                                CompilationManager.class.getName(),
603:                                "051018-774"));
604:                        return false;
605:                    } else if (recompileSwitch == "always") {
606:                        return false;
607:                    } else if (recompileSwitch == "never") {
608:                        return objectFile.exists();
609:                    } else if (recompileSwitch == "check") {
610:                        CachedInfo info = (CachedInfo) item.getMetaData();
611:                        DependencyTracker tracker = null;
612:                        if (info != null) {
613:                            tracker = info.getDependencyTracker();
614:                        }
615:                        // Set up the properties, for dependency checking
616:                        props = (Properties) props.clone();
617:                        return (tracker != null) && tracker.isUpToDate(props);
618:                    } else {
619:                        throw new IllegalArgumentException(
620:                        /* (non-Javadoc)
621:                         * @i18n.test
622:                         * @org-mes="invalid value for 'recompile' property"
623:                         */
624:                        org.openlaszlo.i18n.LaszloMessages.getMessage(
625:                                CompilationManager.class.getName(),
626:                                "051018-797"));
627:                    }
628:                } catch (Exception ex) {
629:                    CompilationError e = new CompilationError(ex);
630:                    e.initPathname(sourceFile.getPath());
631:                    throw e;
632:                }
633:            }
634:
635:            /**
636:             * Compiles the file named by pathname and leaves the result 
637:             * in the cached item.  If the file can't be compiled and
638:             * debugCompilationErrors is true, returns an HTML document
639:             * describing the error; otherwise, passes the exception.
640:             *
641:             * @param pathname a <code>String</code> value.  If
642:             * <var>pathname</var> is relative, it is resolved relative to the
643:             * CompilationManager's <var>sourceDirectory</var>.
644:             * @param props properties that affect the compile.
645:             * @return the bytes of the object file
646:             * @exception CompilationError if an error occurs
647:             *
648:             * The PROPS parameter may contain 
649:             * <ul>
650:             * <li>"Content-Encoding" =&gt; the encoding of the output (ignore if null)
651:             * </ul>
652:             */
653:            public synchronized void compileItem(Item item, String pathname,
654:                    Properties compilationProperties) throws CompilationError {
655:                File sourceFile = new File(mSourceDirectory, pathname);
656:                File objectFile = new File(item.getPathName());
657:
658:                try {
659:
660:                    item.markDirty();
661:
662:                    org.openlaszlo.compiler.Compiler compiler = new org.openlaszlo.compiler.Compiler();
663:                    // For each property compiler.name=value, set a
664:                    // compiler property name=value (that is, without
665:                    // the "compiler." prefix)
666:                    for (java.util.Enumeration e = getProperties()
667:                            .propertyNames(); e.hasMoreElements();) {
668:                        String key = (String) e.nextElement();
669:                        if (key.startsWith("compiler.")) {
670:                            compiler.setProperty(key.substring("compiler."
671:                                    .length()), getProperties()
672:                                    .getProperty(key));
673:                        }
674:                    }
675:                    DependencyTracker dependencyTracker = new DependencyTracker(
676:                            compilationProperties);
677:                    TrackingFileResolver resolver = new TrackingFileResolver(
678:                            compiler.getFileResolver(), dependencyTracker);
679:                    dependencyTracker.addFile(sourceFile);
680:                    if (mLPSJarFile != null) {
681:                        // TODO [bshine 10.19.06] mLPSJarFile doesn't seem to
682:                        // have the correct value. It doesn't point to a real
683:                        // jar.
684:                        dependencyTracker.addFile(mLPSJarFile);
685:                    }
686:                    compiler.setFileResolver(resolver);
687:                    compiler.setMediaCache(mMediaCache);
688:
689:                    Canvas canvas = null;
690:
691:                    File tempFile = null;
692:                    FileInputStream tempFileStream = null;
693:                    try {
694:                        tempFile = File.createTempFile("lzc-", null);
695:                        mLogger.debug(
696:                        /* (non-Javadoc)
697:                         * @i18n.test
698:                         * @org-mes="Temporary file is " + p[0]
699:                         */
700:                        org.openlaszlo.i18n.LaszloMessages.getMessage(
701:                                CompilationManager.class.getName(),
702:                                "051018-663", new Object[] { tempFile
703:                                        .getAbsolutePath() }));
704:
705:                        mLogger.debug(
706:                        /* (non-Javadoc)
707:                         * @i18n.test
708:                         * @org-mes="Compiling " + p[0] + " to " + p[1]
709:                         */
710:                        org.openlaszlo.i18n.LaszloMessages.getMessage(
711:                                CompilationManager.class.getName(),
712:                                "051018-883", new Object[] {
713:                                        sourceFile.toString(),
714:                                        tempFile.toString() }));
715:                        canvas = compiler.compile(sourceFile, tempFile,
716:                                compilationProperties);
717:
718:                        mLogger.debug(
719:                        /* (non-Javadoc)
720:                         * @i18n.test
721:                         * @org-mes="Canvas size is " + p[0] + " by " + p[1]
722:                         */
723:                        org.openlaszlo.i18n.LaszloMessages.getMessage(
724:                                CompilationManager.class.getName(),
725:                                "051018-894", new Object[] {
726:                                        new Integer(canvas.getWidth()),
727:                                        new Integer(canvas.getHeight()) }));
728:
729:                        tempFileStream = new FileInputStream(tempFile);
730:
731:                        item.update(tempFileStream);
732:                        dependencyTracker.addFile(objectFile);
733:                        String encoding = compilationProperties
734:                                .getProperty(LZHttpUtils.CONTENT_ENCODING);
735:                        // FIXME: [2003-07-21 bloch] the factoring of cm.CacheInfo and cache.CacheInfo
736:                        // has never been right.  Someday, if there are more subclasses of Cache that
737:                        // use the [gs]etMetaData methods, then this should really be fixed.  (bug #1778).
738:                        CachedInfo info = new CachedInfo(dependencyTracker,
739:                                canvas, encoding);
740:                        item.getInfo().setLastModified(
741:                                objectFile.lastModified());
742:                        item.update(info);
743:                        item.markClean();
744:
745:                        // Add security options for this application after compilation
746:                        LPS.configuration.setApplicationOptions(FileUtils
747:                                .relativePath(pathname, LPS.HOME()), canvas
748:                                .getSecurityOptions());
749:
750:                    } finally {
751:                        if (tempFileStream != null) {
752:                            FileUtils.close(tempFileStream);
753:                        }
754:                        if (tempFile != null) {
755:                            tempFile.delete();
756:                        }
757:
758:                        // Cleanup now
759:                        mLogger.debug(
760:                        /* (non-Javadoc)
761:                         * @i18n.test
762:                         * @org-mes="starting gc"
763:                         */
764:                        org.openlaszlo.i18n.LaszloMessages.getMessage(
765:                                CompilationManager.class.getName(),
766:                                "051018-713"));
767:                        System.gc();
768:                        mLogger.debug(
769:                        /* (non-Javadoc)
770:                         * @i18n.test
771:                         * @org-mes="finished gc"
772:                         */
773:                        org.openlaszlo.i18n.LaszloMessages.getMessage(
774:                                CompilationManager.class.getName(),
775:                                "051018-722"));
776:                    }
777:                } catch (IOException ioe) {
778:                    CompilationError e = new CompilationError(ioe);
779:                    e.initPathname(sourceFile.getPath());
780:                    throw e;
781:                }
782:            }
783:
784:            /**
785:             * @return a cache key for the given compile
786:             */
787:            static Serializable computeKey(String pathname, Properties props) {
788:
789:                TreeSet sorted = new TreeSet();
790:                for (java.util.Enumeration e = props.propertyNames(); e
791:                        .hasMoreElements();) {
792:                    String key = (String) e.nextElement();
793:                    // Omit the recompile property
794:                    if (key.equalsIgnoreCase(RECOMPILE))
795:                        continue;
796:
797:                    String value = props.getProperty(key);
798:                    StringBuffer buf = new StringBuffer();
799:                    buf.append(key);
800:                    buf.append(' ');
801:                    buf.append(value);
802:
803:                    sorted.add(buf.toString());
804:                }
805:
806:                StringBuffer buf = new StringBuffer(FileUtils.relativePath(
807:                        pathname, LPS.HOME()));
808:
809:                buf.append(' ');
810:                for (java.util.Iterator e = sorted.iterator(); e.hasNext();) {
811:                    String str = (String) e.next();
812:                    buf.append(str);
813:                }
814:
815:                mLogger.debug(
816:                /* (non-Javadoc)
817:                 * @i18n.test
818:                 * @org-mes="computeKey: " + p[0]
819:                 */
820:                org.openlaszlo.i18n.LaszloMessages.getMessage(
821:                        CompilationManager.class.getName(), "051018-984",
822:                        new Object[] { buf.toString() }));
823:                return buf.toString();
824:            }
825:
826:            /** Given the pathname of a file, return a file name
827:             * for an "source" version of this file that lives in the cache.
828:             * @param srcName path to file in source directory
829:             * @param webappPath real path for web application
830:             * @return a File
831:             */
832:            public File getCacheSourcePath(String srcName, String webappPath) {
833:                // todo: relative to src directory
834:                File src = new File(srcName);
835:                if (src.getParentFile() != null) {
836:                    String baseParent = src.getParentFile().getAbsolutePath();
837:                    if (baseParent != null
838:                            && baseParent.startsWith(mCacheDirectory
839:                                    .getAbsolutePath())) {
840:                        return new File(srcName);
841:                    }
842:                }
843:                // FIXME: [2003-01-21 pkang] webapp real path should match first part of
844:                // source name. CompilationManager and LZServlet will need overhaul to
845:                // support reading directly from war file.
846:                if (webappPath == null || !srcName.startsWith(webappPath))
847:                    throw new RuntimeException(
848:                    /* (non-Javadoc)
849:                     * @i18n.test
850:                     * @org-mes=p[0] + " doesn't begin with " + p[1]
851:                     */
852:                    org.openlaszlo.i18n.LaszloMessages.getMessage(
853:                            CompilationManager.class.getName(), "051018-1015",
854:                            new Object[] { srcName, webappPath }));
855:                String fixedName = srcName.substring(webappPath.length());
856:                return new File(mCacheDirectory, fixedName);
857:            }
858:        }
859:
860:        /** A FileResolver that tracks dependencies.
861:         *
862:         * @author Oliver Steele
863:         */
864:        class TrackingFileResolver implements  FileResolver {
865:            private final FileResolver mBaseResolver;
866:            private final DependencyTracker mDependencies;
867:
868:            TrackingFileResolver(FileResolver baseResolver,
869:                    DependencyTracker tracker) {
870:                this .mBaseResolver = baseResolver;
871:                this .mDependencies = tracker;
872:            }
873:
874:            public Set getBinaryIncludes() {
875:                return mBaseResolver.getBinaryIncludes();
876:            }
877:
878:            /**
879:             * Implement the FileResolver interface.
880:             *
881:             * @param pathname a <code>String</code> value
882:             * @param base a <code>String</code> value
883:             * @param asLibrary a <code>boolean</code> value
884:             * @return a <code>File</code> value
885:             * @exception FileNotFoundException if an error occurs
886:             */
887:            public File resolve(String pathname, String base, boolean asLibrary)
888:                    throws FileNotFoundException {
889:                File file = mBaseResolver.resolve(pathname, base, asLibrary);
890:                mDependencies.addFile(file);
891:                return file;
892:            }
893:
894:            public File resolve(CompilationEnvironment env, String pathname,
895:                    String base, boolean asLibrary)
896:                    throws FileNotFoundException {
897:                File file = mBaseResolver.resolve(env, pathname, base,
898:                        asLibrary);
899:                mDependencies.addFile(file);
900:                return file;
901:            }
902:
903:            /** For debugging. */
904:            /*void writeResults() {
905:                System.out.println("depends on");
906:                for (java.util.Iterator e = mDependencies.iterator();
907:                     e.hasNext(); ) {
908:                     FileInfo fi = (FileInfo) e.next();
909:                    System.out.println(fi.mPathname + " -> " + fi.mChecksum);
910:                }
911:                }*/
912:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.