Source Code Cross Referenced for Compiler.java in  » Template-Engine » Tea » com » go » tea » compiler » 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 » Template Engine » Tea » com.go.tea.compiler 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* ====================================================================
002:         * Tea - Copyright (c) 1997-2000 Walt Disney Internet Group
003:         * ====================================================================
004:         * The Tea Software License, Version 1.1
005:         *
006:         * Copyright (c) 2000 Walt Disney Internet Group. All rights reserved.
007:         *
008:         * Redistribution and use in source and binary forms, with or without
009:         * modification, are permitted provided that the following conditions
010:         * are met:
011:         *
012:         * 1. Redistributions of source code must retain the above copyright
013:         *    notice, this list of conditions and the following disclaimer.
014:         *
015:         * 2. Redistributions in binary form must reproduce the above copyright
016:         *    notice, this list of conditions and the following disclaimer in
017:         *    the documentation and/or other materials provided with the
018:         *    distribution.
019:         *
020:         * 3. The end-user documentation included with the redistribution,
021:         *    if any, must include the following acknowledgment:
022:         *       "This product includes software developed by the
023:         *        Walt Disney Internet Group (http://opensource.go.com/)."
024:         *    Alternately, this acknowledgment may appear in the software itself,
025:         *    if and wherever such third-party acknowledgments normally appear.
026:         *
027:         * 4. The names "Tea", "TeaServlet", "Kettle", "Trove" and "BeanDoc" must
028:         *    not be used to endorse or promote products derived from this
029:         *    software without prior written permission. For written
030:         *    permission, please contact opensource@dig.com.
031:         *
032:         * 5. Products derived from this software may not be called "Tea",
033:         *    "TeaServlet", "Kettle" or "Trove", nor may "Tea", "TeaServlet",
034:         *    "Kettle", "Trove" or "BeanDoc" appear in their name, without prior
035:         *    written permission of the Walt Disney Internet Group.
036:         *
037:         * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
038:         * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
039:         * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
040:         * DISCLAIMED.  IN NO EVENT SHALL THE WALT DISNEY INTERNET GROUP OR ITS
041:         * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
042:         * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
043:         * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
044:         * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
045:         * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
046:         * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
047:         * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
048:         * ====================================================================
049:         *
050:         * For more information about Tea, please see http://opensource.go.com/.
051:         */
052:
053:        package com.go.tea.compiler;
054:
055:        import java.io.*;
056:        import java.util.*;
057:        import java.lang.reflect.*;
058:        import com.go.trove.io.SourceReader;
059:        import com.go.tea.parsetree.*;
060:
061:        /******************************************************************************
062:         * The Tea compiler. This class is abstract, and a few concrete
063:         * implementations can be found in the com.go.tea.util package.
064:         *
065:         * <p>A Compiler instance should be used for only one "build" because
066:         * some information is cached internally like parse trees and error count.
067:         *
068:         * @author Brian S O'Neill
069:         * @version
070:         * <!--$$Revision:--> 58 <!-- $-->, <!--$$JustDate:-->  7/26/01 <!-- $-->
071:         * @see com.go.tea.util.FileCompiler
072:         * @see com.go.tea.util.ResourceCompiler
073:         */
074:        public abstract class Compiler {
075:            // Maps qualified names to ParseTrees.
076:            final Map mParseTreeMap;
077:
078:            // Maps qualified names to CompilationUnits.
079:            private final Map mCompilationUnitMap = new HashMap();
080:
081:            // Set of names for CompilationUnits that have already been compiled.
082:            private final Set mCompiled = new HashSet();
083:
084:            private Set mPreserveTree;
085:
086:            private Class mContextClass = com.go.tea.runtime.UtilityContext.class;
087:            private Method[] mRuntimeMethods;
088:            private Method[] mStringConverters;
089:
090:            private ErrorListener mErrorListener;
091:
092:            private Vector mErrorListeners = new Vector(4);
093:            private int mErrorCount = 0;
094:
095:            private Vector mStatusListeners = new Vector();
096:
097:            private boolean mGenerateCode = true;
098:            private boolean mExceptionGuardian = false;
099:
100:            private ClassLoader mClassLoader;
101:
102:            private MessageFormatter mFormatter;
103:
104:            public Compiler() {
105:                this (Collections.synchronizedMap(new HashMap()));
106:            }
107:
108:            /**
109:             * This constructor allows template signatures to be shared among compiler
110:             * instances. This is useful in interactive environments, where compilation
111:             * is occurring on a regular basis, but most called templates are not
112:             * being modified. The Compiler will map qualified template names to
113:             * ParseTree objects that have their code removed. Removing a template
114:             * entry from the map will force the compiler to re-parse the template if
115:             * it is called. Any template passed into the compile method will always be
116:             * re-parsed, even if its parse tree is already present in the map.
117:             *
118:             * @param parseTreeMap map should be thread-safe
119:             */
120:            public Compiler(Map parseTreeMap) {
121:                mParseTreeMap = parseTreeMap;
122:                mErrorListener = new ErrorListener() {
123:                    public void compileError(ErrorEvent e) {
124:                        dispatchCompileError(e);
125:                    }
126:                };
127:                mFormatter = MessageFormatter.lookup(this );
128:            }
129:
130:            /**
131:             * Add an ErrorListener in order receive events of compile-time errors.
132:             * @see com.go.tea.util.ConsoleErrorReporter
133:             */
134:            public void addErrorListener(ErrorListener listener) {
135:                mErrorListeners.addElement(listener);
136:            }
137:
138:            public void removeErrorListener(ErrorListener listener) {
139:                mErrorListeners.removeElement(listener);
140:            }
141:
142:            private void dispatchCompileError(ErrorEvent e) {
143:                mErrorCount++;
144:
145:                synchronized (mErrorListeners) {
146:                    for (int i = 0; i < mErrorListeners.size(); i++) {
147:                        ((ErrorListener) mErrorListeners.elementAt(i))
148:                                .compileError(e);
149:                    }
150:                }
151:            }
152:
153:            /**
154:             * Add a StatusListener in order to receive events of compilation progress.
155:             */
156:            public void addStatusListener(StatusListener listener) {
157:                mStatusListeners.addElement(listener);
158:            }
159:
160:            public void removeStatusListener(StatusListener listener) {
161:                mStatusListeners.removeElement(listener);
162:            }
163:
164:            private void dispatchCompileStatus(StatusEvent e) {
165:                synchronized (mStatusListeners) {
166:                    for (int i = 0; i < mStatusListeners.size(); i++) {
167:                        ((StatusListener) mStatusListeners.elementAt(i))
168:                                .statusUpdate(e);
169:                    }
170:                }
171:            }
172:
173:            private void uncaughtException(Exception e) {
174:                Thread t = Thread.currentThread();
175:                t.getThreadGroup().uncaughtException(t, e);
176:            }
177:
178:            /**
179:             * By default, code generation is enabled. Passing false disables the
180:             * code generation phase of the compiler.
181:             */
182:            public void setCodeGenerationEnabled(boolean flag) {
183:                mGenerateCode = flag;
184:            }
185:
186:            /**
187:             * Returns true if code generation is enabled. The default setting is true.
188:             */
189:            public boolean isCodeGenerationEnabled() {
190:                return mGenerateCode;
191:            }
192:
193:            public void setExceptionGuardianEnabled(boolean flag) {
194:                mExceptionGuardian = flag;
195:            }
196:
197:            /**
198:             * Returns true if the exception guardian is enabled. The default setting
199:             * is false.
200:             */
201:            public boolean isExceptionGuardianEnabled() {
202:                return mExceptionGuardian;
203:            }
204:
205:            /**
206:             * Sets the ClassLoader to use to load classes with. If set to null,
207:             * then classes are loaded using Class.forName.
208:             */
209:            public void setClassLoader(ClassLoader loader) {
210:                mClassLoader = loader;
211:            }
212:
213:            /**
214:             * Returns the ClassLoader used by the Compiler, or null if none set.
215:             */
216:            public ClassLoader getClassLoader() {
217:                return mClassLoader;
218:            }
219:
220:            /**
221:             * Loads and returns a class by the fully qualified name given. If a
222:             * ClassLoader is specified, it is used to load the class. Otherwise,
223:             * the class is loaded via Class.forName.
224:             *
225:             * @see #setClassLoader(ClassLoader)
226:             */
227:            public Class loadClass(String name) throws ClassNotFoundException {
228:                while (true) {
229:                    try {
230:                        if (mClassLoader == null) {
231:                            return Class.forName(name);
232:                        } else {
233:                            return mClassLoader.loadClass(name);
234:                        }
235:                    } catch (ClassNotFoundException e) {
236:                        int index = name.lastIndexOf('.');
237:                        if (index < 0) {
238:                            throw e;
239:                        }
240:
241:                        // Search for inner class.
242:                        name = name.substring(0, index) + '$'
243:                                + name.substring(index + 1);
244:                    }
245:                }
246:            }
247:
248:            /**
249:             * After a template is compiled, all but the root node of its parse tree
250:             * is clipped, in order to save memory. Applications that wish to traverse
251:             * CompilationUnit parse trees should call this method to preserve them.
252:             * This method must be called prior to compilation and prior to requesting
253:             * a parse tree from a CompilationUnit.
254:             *
255:             * @param name fully qualified name of template whose parse tree is to be
256:             * preserved.
257:             */
258:            public void preserveParseTree(String name) {
259:                if (mPreserveTree == null) {
260:                    mPreserveTree = new HashSet();
261:                }
262:                mPreserveTree.add(name);
263:            }
264:
265:            /**
266:             * Compile a single compilation unit. This method can be called multiple
267:             * times, but it will not compile compilation units that have already been
268:             * compiled.
269:             *
270:             * @param name the fully qualified template name
271:             *
272:             * @return The names of all the sources compiled by this compiler
273:             * @exception IOException
274:             */
275:            public String[] compile(String name) throws IOException {
276:                return compile(new String[] { name });
277:            }
278:
279:            /**
280:             * Compile a list of compilation units. This method can be called multiple
281:             * times, but it will not compile compilation units that have already been
282:             * compiled.
283:             *
284:             * @param names an array of fully qualified template names
285:             *
286:             * @return The names of all the sources compiled by this compiler
287:             * @exception IOException
288:             */
289:            public String[] compile(String[] names) throws IOException {
290:                synchronized (mParseTreeMap) {
291:                    for (int i = 0; i < names.length; i++) {
292:                        if (Thread.interrupted()) {
293:                            break;
294:                        }
295:                        dispatchCompileStatus(new StatusEvent(this , i,
296:                                names.length, names[i]));
297:                        CompilationUnit unit = getCompilationUnit(names[i],
298:                                null);
299:                        if (unit == null) {
300:                            String msg = mFormatter.format("not.found",
301:                                    names[i]);
302:                            dispatchCompileError(new ErrorEvent(this , msg,
303:                                    (SourceInfo) null, null));
304:                        } else if (!mCompiled.contains(names[i])
305:                                && unit.shouldCompile()) {
306:                            mParseTreeMap.remove(names[i]);
307:                            getParseTree(unit);
308:                        }
309:                    }
310:                }
311:
312:                names = new String[mCompiled.size()];
313:                Iterator it = mCompiled.iterator();
314:                int i = 0;
315:                while (it.hasNext()) {
316:                    names[i++] = (String) it.next();
317:                }
318:
319:                return names;
320:            }
321:
322:            public int getErrorCount() {
323:                return mErrorCount;
324:            }
325:
326:            /**
327:             * Returns a compilation unit associated with the given name, or null if
328:             * not found.
329:             *
330:             * @param name the requested name
331:             * @param from optional CompilationUnit is passed because requested name
332:             * should be found relative to it.
333:             */
334:            public CompilationUnit getCompilationUnit(String name,
335:                    CompilationUnit from) {
336:                name = determineQualifiedName(name, from);
337:
338:                if (name == null) {
339:                    return null;
340:                }
341:
342:                CompilationUnit unit = (CompilationUnit) mCompilationUnitMap
343:                        .get(name);
344:                if (unit == null) {
345:                    unit = createCompilationUnit(name);
346:                    if (unit != null) {
347:                        mCompilationUnitMap.put(name, unit);
348:                    }
349:                }
350:
351:                return unit;
352:            }
353:
354:            /**
355:             * Returns the list of imported packages that all templates have. This
356:             * always returns "java.lang" and "java.util". Template parameters can
357:             * abbreviate the names of all classes in java.lang and java.util.
358:             */
359:            public static final String[] getImportedPackages() {
360:                return new String[] { "java.lang", "java.util" };
361:            }
362:
363:            /**
364:             * Return a class that defines a template's runtime context. The runtime
365:             * context contains methods that are callable by templates. A template
366:             * is compiled such that the first parameter of its execute method must
367:             * be an instance of the runtime context.
368:             *
369:             * <p>Default implementation returns
370:             * com.go.tea.runtime.UtilityContext.
371:             *
372:             * @see com.go.tea.runtime.UtilityContext
373:             */
374:            public Class getRuntimeContext() {
375:                return mContextClass;
376:            }
377:
378:            /**
379:             * Call to override the default runtime context class that a template is
380:             * compiled to use.
381:             *
382:             * @see com.go.tea.runtime.Context
383:             */
384:            public void setRuntimeContext(Class contextClass) {
385:                mContextClass = contextClass;
386:                mRuntimeMethods = null;
387:                mStringConverters = null;
388:            }
389:
390:            /**
391:             * Returns all the methods available in the runtime context.
392:             */
393:            public final Method[] getRuntimeContextMethods() {
394:                if (mRuntimeMethods == null) {
395:                    mRuntimeMethods = getRuntimeContext().getMethods();
396:                }
397:
398:                return (Method[]) mRuntimeMethods.clone();
399:            }
400:
401:            /**
402:             * Return the name of a method in the runtime context to bind to for 
403:             * receiving objects emitted by templates. The compiler will bind to the 
404:             * closest matching public method based on the type of its single 
405:             * parameter.
406:             *
407:             * <p>Default implementation returns "print".
408:             */
409:            public String getRuntimeReceiver() {
410:                return "print";
411:            }
412:
413:            /**
414:             * Return the name of a method in the runtime context to bind to for 
415:             * converting objects and primitives to strings. The compiler will bind to 
416:             * the closest matching public method based on the type of its single 
417:             * parameter.
418:             *
419:             * <p>Default implementation returns "toString". Returning null indicates 
420:             * that a static String.valueOf method should be invoked.
421:             */
422:            public String getRuntimeStringConverter() {
423:                return "toString";
424:            }
425:
426:            /**
427:             * Returns the set of methods that are used to perform conversion to
428:             * strings. The compiler will bind to the closest matching method based
429:             * on its parameter type.
430:             */
431:            public final Method[] getStringConverterMethods() {
432:                if (mStringConverters == null) {
433:                    String name = getRuntimeStringConverter();
434:
435:                    Vector methods = new Vector();
436:
437:                    if (name != null) {
438:                        Method[] contextMethods = getRuntimeContextMethods();
439:                        for (int i = 0; i < contextMethods.length; i++) {
440:                            Method m = contextMethods[i];
441:                            if (m.getName().equals(name)
442:                                    && m.getReturnType() == String.class
443:                                    && m.getParameterTypes().length == 1) {
444:
445:                                methods.addElement(m);
446:                            }
447:                        }
448:                    }
449:
450:                    int customSize = methods.size();
451:
452:                    Method[] stringMethods = String.class.getMethods();
453:                    for (int i = 0; i < stringMethods.length; i++) {
454:                        Method m = stringMethods[i];
455:                        if (m.getName().equals("valueOf")
456:                                && m.getReturnType() == String.class
457:                                && m.getParameterTypes().length == 1
458:                                && Modifier.isStatic(m.getModifiers())) {
459:
460:                            // Don't add to list if a custom converter already handles
461:                            // this method's parameter type.
462:                            Class type = m.getParameterTypes()[0];
463:                            int j;
464:                            for (j = 0; j < customSize; j++) {
465:                                Method cm = (Method) methods.elementAt(j);
466:                                if (cm.getParameterTypes()[0] == type) {
467:                                    break;
468:                                }
469:                            }
470:
471:                            if (j == customSize) {
472:                                methods.addElement(m);
473:                            }
474:                        }
475:                    }
476:
477:                    mStringConverters = new Method[methods.size()];
478:                    methods.copyInto(mStringConverters);
479:                }
480:
481:                return (Method[]) mStringConverters.clone();
482:            }
483:
484:            /**
485:             * Given a name, as requested by the given CompilationUnit, return a
486:             * fully qualified name or null if the name could not be found.
487:             *
488:             * @param name requested name
489:             * @param from optional CompilationUnit
490:             */
491:            private String determineQualifiedName(String name,
492:                    CompilationUnit from) {
493:                if (from != null) {
494:                    // Determine qualified name as being relative to "from"
495:
496:                    String fromName = from.getName();
497:                    int index = fromName.lastIndexOf('.');
498:                    if (index >= 0) {
499:                        String qual = fromName.substring(0, index + 1) + name;
500:                        if (sourceExists(qual)) {
501:                            return qual;
502:                        }
503:                    }
504:                }
505:
506:                if (sourceExists(name)) {
507:                    return name;
508:                }
509:
510:                return null;
511:            }
512:
513:            /**
514:             * @return true if source exists for the given qualified name
515:             */
516:            public abstract boolean sourceExists(String name);
517:
518:            protected abstract CompilationUnit createCompilationUnit(String name);
519:
520:            /**
521:             * Default implementation returns a SourceReader that uses "<%" and "%>" 
522:             * as code delimiters.
523:             */
524:            protected SourceReader createSourceReader(CompilationUnit unit)
525:                    throws IOException {
526:
527:                Reader r = new BufferedReader(unit.getReader());
528:                return new SourceReader(r, "<%", "%>");
529:            }
530:
531:            protected Scanner createScanner(SourceReader reader,
532:                    CompilationUnit unit) throws IOException {
533:
534:                return new Scanner(reader, unit);
535:            }
536:
537:            protected Parser createParser(Scanner scanner, CompilationUnit unit)
538:                    throws IOException {
539:
540:                return new Parser(scanner, unit);
541:            }
542:
543:            protected TypeChecker createTypeChecker(CompilationUnit unit) {
544:                TypeChecker tc = new TypeChecker(unit);
545:                tc.setClassLoader(getClassLoader());
546:                tc.setExceptionGuardianEnabled(isExceptionGuardianEnabled());
547:                return tc;
548:            }
549:
550:            /**
551:             * Default implementation returns a new JavaClassGenerator.
552:             *
553:             * @see JavaClassGenerator
554:             */
555:            protected CodeGenerator createCodeGenerator(CompilationUnit unit)
556:                    throws IOException {
557:
558:                return new JavaClassGenerator(unit);
559:            }
560:
561:            /**
562:             * Called by the Compiler or by a CompilationUnit when its parse tree is 
563:             * requested. Requesting a parse tree may cause template code to be
564:             * generated.
565:             */
566:            Template getParseTree(CompilationUnit unit) {
567:                synchronized (mParseTreeMap) {
568:                    return getParseTree0(unit);
569:                }
570:            }
571:
572:            private Template getParseTree0(CompilationUnit unit) {
573:                String name = unit.getName();
574:                Template tree = (Template) mParseTreeMap.get(name);
575:                if (tree != null) {
576:                    return tree;
577:                }
578:
579:                try {
580:                    // Parse and type check the parse tree.
581:
582:                    // Direct all compile errors into the CompilationUnit.
583:                    // Remove the unit as an ErrorListener in the finally block
584:                    // at the end of this method.
585:                    addErrorListener(unit);
586:
587:                    try {
588:                        Scanner s = createScanner(createSourceReader(unit),
589:                                unit);
590:                        s.addErrorListener(mErrorListener);
591:                        Parser p = createParser(s, unit);
592:                        p.addErrorListener(mErrorListener);
593:                        tree = p.parse();
594:                        mParseTreeMap.put(name, tree);
595:                        s.close();
596:                    } catch (IOException e) {
597:                        uncaughtException(e);
598:                        String msg = mFormatter.format("read.error", e
599:                                .toString());
600:                        dispatchCompileError(new ErrorEvent(this , msg,
601:                                (SourceInfo) null, unit));
602:                        return tree;
603:                    }
604:
605:                    TypeChecker tc = createTypeChecker(unit);
606:                    tc.setClassLoader(getClassLoader());
607:                    tc.addErrorListener(mErrorListener);
608:                    tc.typeCheck();
609:
610:                    if (mCompiled.contains(name) || !unit.shouldCompile()) {
611:                        return tree;
612:                    } else {
613:                        mCompiled.add(name);
614:                    }
615:
616:                    // Code generate the CompilationUnit only if no errors and
617:                    // the code generate option is enabled.
618:
619:                    if (unit.getErrorCount() == 0 && mGenerateCode) {
620:                        try {
621:                            OutputStream out = unit.getOutputStream();
622:
623:                            if (out != null) {
624:                                tree = (Template) new BasicOptimizer(tree)
625:                                        .optimize();
626:                                mParseTreeMap.put(name, tree);
627:
628:                                CodeGenerator codegen = createCodeGenerator(unit);
629:                                codegen.writeTo(out);
630:                                out.flush();
631:                                out.close();
632:                            }
633:                        } catch (IOException e) {
634:                            uncaughtException(e);
635:                            String msg = mFormatter.format("write.error", e
636:                                    .toString());
637:                            dispatchCompileError(new ErrorEvent(this , msg,
638:                                    (SourceInfo) null, unit));
639:                            return tree;
640:                        }
641:                    }
642:                } catch (Exception e) {
643:                    uncaughtException(e);
644:                    String msg = mFormatter.format("internal.error", e
645:                            .toString());
646:                    dispatchCompileError(new ErrorEvent(this , msg,
647:                            (SourceInfo) null, unit));
648:                } finally {
649:                    removeErrorListener(unit);
650:                    // Conserve memory by removing the bulk of the parse tree after
651:                    // compilation. This preserves the signature for templates that
652:                    // may need to call this one.
653:                    if (tree != null && mPreserveTree != null
654:                            && !mPreserveTree.contains(name)) {
655:                        tree.setStatement(null);
656:                    }
657:                }
658:
659:                return tree;
660:            }
661:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.