Source Code Cross Referenced for JSPCompiler.java in  » Web-Server » Acme-WebServer » org » gjt » jsp » 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 » Web Server » Acme WebServer » org.gjt.jsp 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:        	GNUJSP - a free JSP implementation
0003:        	Copyright (C) 1998-1999, Vincent Partington <vinny@klomp.org>
0004:
0005:        	This program is free software; you can redistribute it and/or
0006:        	modify it under the terms of the GNU General Public License
0007:        	as published by the Free Software Foundation; either version 2
0008:        	of the License, or (at your option) any later version.
0009:
0010:        	This program is distributed in the hope that it will be useful,
0011:        	but WITHOUT ANY WARRANTY; without even the implied warranty of
0012:        	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013:        	GNU General Public License for more details.
0014:
0015:        	You should have received a copy of the GNU General Public License
0016:        	along with this program; if not, write to the Free Software
0017:        	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
0018:         */
0019:
0020:        package org.gjt.jsp;
0021:
0022:        import java.io.BufferedReader;
0023:        import java.io.ByteArrayOutputStream;
0024:        import java.io.File;
0025:        import java.io.FileNotFoundException;
0026:        import java.io.FileReader;
0027:        import java.io.FileWriter;
0028:        import java.io.IOException;
0029:        import java.io.InputStreamReader;
0030:        import java.io.LineNumberReader;
0031:        import java.io.OutputStream;
0032:        import java.io.PrintStream;
0033:        import java.io.PrintWriter;
0034:        import java.io.StringReader;
0035:        import java.util.Enumeration;
0036:        import java.util.Hashtable;
0037:        import java.util.Properties;
0038:        import java.util.StringTokenizer;
0039:        import java.util.Vector;
0040:
0041:        import javax.servlet.http.HttpServletRequest;
0042:        import javax.servlet.http.HttpServletResponse;
0043:
0044:        import Acme.Utils;
0045:
0046:        /**
0047:         * This JSP compiler class takes the quick&dirty approach to JSP parsing.
0048:         * The whole JSP file is read into memory and an index is run through it
0049:         * until a StringIndexOutOfBoundsException occurs. I was happily hacking
0050:         * away at this until I discovered it had gotten more than 30K long. It
0051:         * seems to work, but someday it might be a good idea to break this
0052:         * all up into separate classes, like a JSPParser, JavaGenerator en
0053:         * JavaCompiler class.
0054:         *
0055:         * A new JSPCompiler should be created every time a file is compiled.
0056:         * The classfiles directory, the file and the classname are parameters
0057:         * to the constructor. Call compile() to do the actual compiling.
0058:         */
0059:        public class JSPCompiler {
0060:            public static final int COMPILER_VERSION_NR = 4;
0061:
0062:            private static final int PARSE_NONE = 0, PARSE_HTML = 1,
0063:                    PARSE_DECLARATION = 2, PARSE_SCRIPTLET = 3,
0064:                    PARSE_EXPRESSION = 4;
0065:
0066:            private static final String lineSeparator = System
0067:                    .getProperty("line.separator"),
0068:                    encodedLineSeparator = javaStringEncode(System
0069:                            .getProperty("line.separator"));
0070:
0071:            private JSPServlet jspServlet;
0072:            private File jspFile, javaFile, classFile;
0073:            private String className;
0074:            private HttpServletRequest servletRequest;
0075:
0076:            private String src;
0077:            private int srcPos, lineNr;
0078:
0079:            private int parseState = PARSE_NONE;
0080:            private boolean justWroteNewline = false;
0081:
0082:            private Vector dependencies = new Vector();
0083:            private boolean createSession = false;
0084:            private String content_typeDirective = null;
0085:            private StringBuffer extendsDirective = new StringBuffer(),
0086:                    implements Directive = new StringBuffer(),
0087:                    importDirective = new StringBuffer(),
0088:                    methodDirective = new StringBuffer(),
0089:                    declarationsCode = new StringBuffer(),
0090:                    beanCode = new StringBuffer(),
0091:                    scriptletsCode = new StringBuffer();
0092:
0093:            /**
0094:             * Create a JSPCompiler object.
0095:             */
0096:            public JSPCompiler(JSPServlet jspServlet, File jspFile,
0097:                    String className, HttpServletRequest servletRequest) {
0098:                this .jspServlet = jspServlet;
0099:                this .jspFile = jspFile;
0100:                this .javaFile = getFileForClass(jspServlet.repository,
0101:                        className, ".java");
0102:                this .classFile = getFileForClass(jspServlet.repository,
0103:                        className, ".class");
0104:                this .className = className;
0105:                this .servletRequest = servletRequest;
0106:            }
0107:
0108:            /**
0109:             * Do the actual compilation. This is done in three phases:
0110:             * <OL>
0111:             * <LI>parse the JSP file
0112:             * <LI>generate a <CODE>.java</CODE> file
0113:             * <LI>compile the <CODE>.java</CODE> file into a <CODE>.class</CODE> file
0114:             * </OL>
0115:             *
0116:             * @exception JSPException is thrown when a compilation error occurs
0117:             */
0118:            public void compile() throws JSPException {
0119:                parseJspFile();
0120:                generateJavaFile();
0121:                compileJavaFile();
0122:            }
0123:
0124:            private void parseJspFile() throws JSPException {
0125:                parseOneJspFile();
0126:                changeParseState(PARSE_NONE);
0127:
0128:                if (content_typeDirective == null) {
0129:                    content_typeDirective = jspServlet.defaultContentType;
0130:                }
0131:                if (extendsDirective.length() == 0) {
0132:                    extendsDirective.append("javax.servlet.http.HttpServlet");
0133:                }
0134:                if (methodDirective.length() == 0) {
0135:                    methodDirective.append("service");
0136:                }
0137:            }
0138:
0139:            private void parseOneJspFile() throws JSPException {
0140:                BufferedReader in;
0141:                StringBuffer srcBuf;
0142:                String s;
0143:                int i;
0144:                char c, d;
0145:
0146:                // read jsp source
0147:                dependencies.addElement(jspFile);
0148:                dependencies.addElement(new Long(jspFile.lastModified()));
0149:                try {
0150:                    in = new BufferedReader(new FileReader(jspFile));
0151:                    try {
0152:                        srcBuf = new StringBuffer((int) jspFile.length());
0153:                        while ((s = in.readLine()) != null) {
0154:                            srcBuf.append(s).append((char) '\n');
0155:                        }
0156:                        src = srcBuf.toString();
0157:                        srcBuf = null;
0158:                    } finally {
0159:                        in.close();
0160:                    }
0161:                } catch (FileNotFoundException fnfexc) {
0162:                    throw new JSPException(HttpServletResponse.SC_NOT_FOUND,
0163:                            "File " + jspFile + " could not be found");
0164:                } catch (IOException ioexc) {
0165:                    throw new JSPException(ioexc.toString());
0166:                }
0167:
0168:                // parse jsp source
0169:                lineNr = 1;
0170:                srcPos = 0;
0171:                try {
0172:                    PARSING: for (;;) {
0173:                        c = src.charAt(srcPos);
0174:
0175:                        // check for possible state change
0176:                        if (c == '<') {
0177:                            if (parseState == PARSE_NONE
0178:                                    || parseState == PARSE_HTML) {
0179:                                if (parseInNoneOrHtmlState()) {
0180:                                    continue PARSING;
0181:                                }
0182:                            } else if (parseState == PARSE_DECLARATION) {
0183:                                if (parseInDeclarationState()) {
0184:                                    continue PARSING;
0185:                                }
0186:                            }
0187:                        } else if (c == '%'
0188:                                && (parseState == PARSE_EXPRESSION || parseState == PARSE_SCRIPTLET)
0189:                                && (srcPos < src.length() - 1 && src
0190:                                        .charAt(srcPos + 1) == '>')) {
0191:                            // end of expression or scriptlet
0192:                            changeParseState(PARSE_NONE);
0193:                            srcPos += 2;
0194:                            continue PARSING;
0195:                        }
0196:
0197:                        // output character
0198:                        switch (parseState) {
0199:                        case PARSE_NONE:
0200:                            changeParseState(PARSE_HTML);
0201:                        case PARSE_HTML:
0202:                            if (justWroteNewline && c != '\n') {
0203:                                justWroteNewline = false;
0204:                                scriptletsCode.append("\" +").append(
0205:                                        lineSeparator).append("\t\t\t\"");
0206:                            }
0207:
0208:                            switch (c) {
0209:                            case '\b':
0210:                                scriptletsCode.append("\\b");
0211:                                break;
0212:                            case '\t':
0213:                                scriptletsCode.append("\\t");
0214:                                break;
0215:                            case '\n':
0216:                                scriptletsCode.append(encodedLineSeparator);
0217:                                justWroteNewline = true;
0218:                                lineNr++;
0219:                                break;
0220:                            case '\f':
0221:                                scriptletsCode.append("\\f");
0222:                                break;
0223:                            case '\'':
0224:                                scriptletsCode.append("\\\'");
0225:                                break;
0226:                            case '\"':
0227:                                scriptletsCode.append("\\\"");
0228:                                break;
0229:                            case '\\':
0230:                                scriptletsCode.append("\\\\");
0231:                                break;
0232:                            default:
0233:                                if (c > 0xFF) {
0234:                                    s = "00" + Integer.toHexString(c);
0235:                                    scriptletsCode.append("\\u").append(
0236:                                            s.substring(s.length() - 4));
0237:                                } else if (c < ' ' || c >= 0x7F) {
0238:                                    s = "00" + Integer.toOctalString(c);
0239:                                    scriptletsCode.append((char) '\\').append(
0240:                                            s.substring(s.length() - 3));
0241:                                } else {
0242:                                    scriptletsCode.append((char) c);
0243:                                }
0244:                                break;
0245:                            }
0246:                            break;
0247:                        case PARSE_DECLARATION:
0248:                            if (c == '\n') {
0249:                                declarationsCode.append(lineSeparator);
0250:                                lineNr++;
0251:                            } else {
0252:                                declarationsCode.append((char) c);
0253:                            }
0254:                            break;
0255:                        default:
0256:                            if (c == '\n') {
0257:                                scriptletsCode.append(lineSeparator);
0258:                                lineNr++;
0259:                            } else {
0260:                                scriptletsCode.append((char) c);
0261:                            }
0262:                            break;
0263:                        }
0264:                        srcPos++;
0265:                    }
0266:                } catch (StringIndexOutOfBoundsException sioobexc) {
0267:                    // instead of checking for the end of the string ourselves
0268:                    // we let java.lang.String find it. This makes the code
0269:                    // simpeler and more efficient.
0270:                }
0271:            }
0272:
0273:            private boolean parseInNoneOrHtmlState()
0274:                    throws StringIndexOutOfBoundsException, JSPException {
0275:                String[] keyAndValue;
0276:                char d;
0277:
0278:                if (srcPos < src.length() - 3 && src.charAt(srcPos + 1) == '%') {
0279:                    // directive or start of expression or scriptlet
0280:                    d = src.charAt(srcPos + 2);
0281:                    if (d == '=') {
0282:                        // start of expression
0283:                        changeParseState(PARSE_EXPRESSION);
0284:                        setSrcPos(srcPos + 3);
0285:                        return true;
0286:                    } else if (d == '@') {
0287:                        // directive
0288:                        parseDirective();
0289:                        return true;
0290:                    } else {
0291:                        // start of scriplet
0292:                        changeParseState(PARSE_SCRIPTLET);
0293:                        setSrcPos(srcPos + 2);
0294:                        return true;
0295:                    }
0296:                } else if (srcPos < src.length() - 20
0297:                        && src.substring(srcPos + 1, srcPos + 12)
0298:                                .equalsIgnoreCase("!--#INCLUDE")
0299:                        && Character.isWhitespace(src.charAt(srcPos + 12))) {
0300:                    parseSSI();
0301:                    return true;
0302:                } else if (srcPos < src.length() - 20
0303:                        && src.substring(srcPos + 1, srcPos + 7)
0304:                                .equalsIgnoreCase("SCRIPT")
0305:                        && Character.isWhitespace(src.charAt(srcPos + 7))) {
0306:                    // possible start of declaration
0307:                    boolean runatServer = false;
0308:                    int prevSrcPos = srcPos, prevLineNr = lineNr;
0309:
0310:                    srcPos += 7;
0311:                    skipWhitespace();
0312:                    for (;;) {
0313:                        // check for end of tag
0314:                        if (src.charAt(srcPos) == '>') {
0315:                            if (runatServer) {
0316:                                // start of declaration
0317:                                changeParseState(PARSE_DECLARATION);
0318:                                srcPos++;
0319:                                return true;
0320:                            } else {
0321:                                srcPos = prevSrcPos;
0322:                                lineNr = prevLineNr;
0323:                                return false;
0324:                            }
0325:                        }
0326:                        keyAndValue = parseKeyAndValue();
0327:                        if (keyAndValue[0].equalsIgnoreCase("RUNAT")
0328:                                && keyAndValue[1].equalsIgnoreCase("SERVER")) {
0329:                            runatServer = true;
0330:                        }
0331:                    }
0332:                } else if (srcPos < src.length() - 10
0333:                        && src.substring(srcPos + 1, srcPos + 5)
0334:                                .equalsIgnoreCase("BEAN")
0335:                        && Character.isWhitespace(src.charAt(srcPos + 5))) {
0336:                    // bean
0337:                    parseBean();
0338:                    return true;
0339:                }
0340:
0341:                return false;
0342:            }
0343:
0344:            private boolean parseInDeclarationState()
0345:                    throws StringIndexOutOfBoundsException, JSPException {
0346:                if (srcPos < src.length() - 8
0347:                        && src.substring(srcPos + 1, srcPos + 8)
0348:                                .equalsIgnoreCase("/SCRIPT")
0349:                        && (Character.isWhitespace(src.charAt(srcPos + 8)) || src
0350:                                .charAt(srcPos + 8) == '>')) {
0351:                    // end of declaration
0352:                    changeParseState(PARSE_NONE);
0353:                    setSrcPos(src.indexOf('>', srcPos));
0354:                    srcPos++;
0355:                    return true;
0356:                }
0357:                return false;
0358:            }
0359:
0360:            private void parseDirective()
0361:                    throws StringIndexOutOfBoundsException, JSPException {
0362:                String[] keyAndValue;
0363:                StringTokenizer toker;
0364:                char c;
0365:
0366:                srcPos += 3;
0367:                skipWhitespace();
0368:
0369:                for (;;) {
0370:                    // check for end of directive
0371:                    c = src.charAt(srcPos);
0372:                    if (c == '%') {
0373:                        if (src.charAt(srcPos + 1) == '>') {
0374:                            srcPos += 2;
0375:                        } else {
0376:                            srcPos++;
0377:                        }
0378:                        return;
0379:                    } else if (c == '>') {
0380:                        srcPos++;
0381:                        return;
0382:                    }
0383:
0384:                    keyAndValue = parseKeyAndValue();
0385:
0386:                    if (keyAndValue[0].equalsIgnoreCase("content_type")) {
0387:                        // content_type
0388:                        if (content_typeDirective == null) {
0389:                            content_typeDirective = keyAndValue[1];
0390:                        }
0391:                    } else if (keyAndValue[0].equalsIgnoreCase("extends")) {
0392:                        // extends
0393:                        if (extendsDirective.length() == 0) {
0394:                            extendsDirective.append(lineSeparator);
0395:                            recordFileAndLineNr(extendsDirective);
0396:                            extendsDirective.append(keyAndValue[1]);
0397:                        }
0398:                    } else if (keyAndValue[0].equalsIgnoreCase("implements")) {
0399:                        // implements
0400:                        toker = new StringTokenizer(keyAndValue[1], " ,");
0401:                        while (toker.hasMoreTokens()) {
0402:                            if (implements Directive.length() == 0) {
0403:                                implements Directive.append(" implements")
0404:                                        .append(lineSeparator);
0405:                            } else {
0406:                                implements Directive.append(",").append(
0407:                                        lineSeparator);
0408:                            }
0409:                            recordFileAndLineNr(implements Directive);
0410:                            implements Directive.append(toker.nextToken());
0411:                        }
0412:                    } else if (keyAndValue[0].equalsIgnoreCase("import")) {
0413:                        // import
0414:                        toker = new StringTokenizer(keyAndValue[1], " ,");
0415:                        while (toker.hasMoreTokens()) {
0416:                            recordFileAndLineNr(importDirective);
0417:                            importDirective.append("import ").append(
0418:                                    toker.nextToken()).append((char) ';')
0419:                                    .append(lineSeparator);
0420:                        }
0421:                    } else if (keyAndValue[0].equalsIgnoreCase("include")) {
0422:                        // include
0423:                        parseInclude(keyAndValue[1], false);
0424:                    } else if (keyAndValue[0].equalsIgnoreCase("language")) {
0425:                        // language
0426:                        if (!keyAndValue[1].equalsIgnoreCase("java")) {
0427:                            throw new JSPException("<B>" + jspFile.getPath()
0428:                                    + ":" + lineNr
0429:                                    + "</B>: Unknown jsp language "
0430:                                    + keyAndValue[1]);
0431:                        }
0432:                    } else if (keyAndValue[0].equalsIgnoreCase("method")) {
0433:                        // method
0434:                        if (methodDirective.length() == 0) {
0435:                            methodDirective.append(lineSeparator);
0436:                            recordFileAndLineNr(methodDirective);
0437:                            methodDirective.append(keyAndValue[1]);
0438:                        }
0439:                    } else if (keyAndValue[0].equalsIgnoreCase("vinclude")) {
0440:                        // vinclude
0441:                        parseInclude(keyAndValue[1], true);
0442:                    } else {
0443:                        throw new JSPException("<B>" + jspFile.getPath() + ":"
0444:                                + lineNr + "</B>: Unknown jsp directive '<I>"
0445:                                + keyAndValue[0] + "</I>'");
0446:                    }
0447:                }
0448:            }
0449:
0450:            private void parseSSI() throws StringIndexOutOfBoundsException,
0451:                    JSPException {
0452:                String[] keyAndValue;
0453:
0454:                srcPos += 12;
0455:                skipWhitespace();
0456:                keyAndValue = parseKeyAndValue();
0457:
0458:                if (keyAndValue[0].equalsIgnoreCase("FILE")) {
0459:                    parseInclude(keyAndValue[1], false);
0460:                } else if (keyAndValue[0].equalsIgnoreCase("VIRTUAL")) {
0461:                    parseInclude(keyAndValue[1], true);
0462:                } else {
0463:                    throw new JSPException("<B>" + jspFile.getPath() + ":"
0464:                            + lineNr + "</B>: Unknown #INCLUDE parameter "
0465:                            + keyAndValue[0]);
0466:                }
0467:
0468:                setSrcPos(src.indexOf('>', srcPos));
0469:                srcPos++;
0470:            }
0471:
0472:            private void parseInclude(String value, boolean virtual)
0473:                    throws StringIndexOutOfBoundsException, JSPException {
0474:                File prevJspFile;
0475:                String s, prevSrc;
0476:                int prevSrcPos, prevLineNr;
0477:
0478:                prevJspFile = jspFile;
0479:                prevSrc = src;
0480:                prevSrcPos = srcPos;
0481:                prevLineNr = lineNr;
0482:
0483:                try {
0484:                    if (virtual) {
0485:                        s = servletRequest.getRealPath(value);
0486:                        if (s == null)
0487:                            throw new JSPException("<B>" + jspFile.getPath()
0488:                                    + ":" + lineNr + "</B>: Virtual file "
0489:                                    + value
0490:                                    + " could not be mapped to a real file");
0491:                        jspFile = new File(s);
0492:                    } else {
0493:                        jspFile = new File(jspFile.getParent(), value);
0494:                    }
0495:                    try {
0496:                        jspFile = new File(jspFile.getCanonicalPath());
0497:                    } catch (IOException ioexc) {
0498:                        jspFile = new File(jspFile.getAbsolutePath());
0499:                    }
0500:                    parseOneJspFile();
0501:                } finally {
0502:                    jspFile = prevJspFile;
0503:                    src = prevSrc;
0504:                    srcPos = prevSrcPos;
0505:                    lineNr = prevLineNr;
0506:                }
0507:            }
0508:
0509:            private void parseBean() throws StringIndexOutOfBoundsException,
0510:                    JSPException {
0511:                Properties beanAttributes;
0512:                Hashtable beanDefaultProperties;
0513:                Enumeration e;
0514:                String[] keyAndValue;
0515:                String k, v, name, varName, type, introspect, create, scope, beanName, getFromScope;
0516:                int startLineNr, endLineNr, i;
0517:
0518:                startLineNr = lineNr;
0519:                srcPos += 5;
0520:                skipWhitespace();
0521:
0522:                // gather <BEAN> tag parameters
0523:                beanAttributes = new Properties();
0524:                for (;;) {
0525:                    // check for end of tag
0526:                    if (src.charAt(srcPos) == '>') {
0527:                        break;
0528:                    }
0529:                    keyAndValue = parseKeyAndValue();
0530:                    beanAttributes.put(keyAndValue[0].toLowerCase(),
0531:                            keyAndValue[1]);
0532:                }
0533:
0534:                // gather <PARAM> tags
0535:                beanDefaultProperties = new Hashtable();
0536:                for (;;) {
0537:                    setSrcPos(src.indexOf('<', srcPos));
0538:                    if (src.substring(srcPos + 1, srcPos + 6).equalsIgnoreCase(
0539:                            "/BEAN")
0540:                            && (Character.isWhitespace(src.charAt(srcPos + 6)) || src
0541:                                    .charAt(srcPos + 6) == '>')) {
0542:                        // </BEAN> tag
0543:                        setSrcPos(src.indexOf('>', srcPos));
0544:                        srcPos++;
0545:                        break;
0546:                    } else if (src.substring(srcPos + 1, srcPos + 6)
0547:                            .equalsIgnoreCase("PARAM")
0548:                            && Character.isWhitespace(src.charAt(srcPos + 6))) {
0549:                        // <PARAM> tag
0550:                        srcPos += 6;
0551:                        skipWhitespace();
0552:
0553:                        for (;;) {
0554:                            // check for end of tag
0555:                            if (src.charAt(srcPos) == '>') {
0556:                                break;
0557:                            }
0558:                            keyAndValue = parseKeyAndValue();
0559:                            beanDefaultProperties.put(keyAndValue[0],
0560:                                    keyAndValue[1]);
0561:                        }
0562:                    } else {
0563:                        srcPos++;
0564:                    }
0565:                }
0566:
0567:                // check bean attributes
0568:                name = beanAttributes.getProperty("name");
0569:                if (name == null)
0570:                    throw new JSPException(
0571:                            "<B>"
0572:                                    + jspFile.getPath()
0573:                                    + ":"
0574:                                    + lineNr
0575:                                    + "</B>: &lt;BEAN&gt; tag does not have required name attribute");
0576:                varName = beanAttributes.getProperty("varname", name);
0577:                type = beanAttributes.getProperty("type", "Object");
0578:                introspect = beanAttributes.getProperty("introspect", "yes");
0579:                create = beanAttributes.getProperty("create", "yes");
0580:                scope = beanAttributes.getProperty("scope", "request");
0581:                beanName = beanAttributes.getProperty("beanname", type);
0582:                if (scope.equals("request")) {
0583:                    getFromScope = "request.getAttribute(\"";
0584:                } else if (scope.equals("session")) {
0585:                    createSession = true;
0586:                    getFromScope = "__session.getValue(\"";
0587:                } else {
0588:                    throw new JSPException(
0589:                            "<B>"
0590:                                    + jspFile.getPath()
0591:                                    + ":"
0592:                                    + lineNr
0593:                                    + "</B>: &lt;BEAN&gt; tag has invalid scope attribute "
0594:                                    + scope);
0595:                }
0596:
0597:                // generate bean code
0598:                endLineNr = lineNr;
0599:                try {
0600:                    // put back line number for start of <BEAN> tag
0601:                    lineNr = startLineNr;
0602:
0603:                    if (beanCode.length() == 0) {
0604:                        beanCode
0605:                                .append(
0606:                                        "\t\tjava.beans.PropertyDescriptor[] __propertyDescriptors;")
0607:                                .append(lineSeparator);
0608:                    }
0609:
0610:                    // bean retrieval
0611:                    recordFileAndLineNr(beanCode);
0612:                    beanCode.append("\t\t").append(type).append((char) ' ')
0613:                            .append(varName).append(" = null;").append(
0614:                                    lineSeparator);
0615:
0616:                    recordFileAndLineNr(beanCode);
0617:                    beanCode.append("\t\t").append("if(").append(getFromScope)
0618:                            .append(javaStringEncode(name)).append(
0619:                                    "\") instanceof ").append(type).append(
0620:                                    ") {").append(lineSeparator);
0621:
0622:                    recordFileAndLineNr(beanCode);
0623:                    beanCode.append("\t\t\t").append(varName).append(" = (")
0624:                            .append(type).append(") ").append(getFromScope)
0625:                            .append(javaStringEncode(name)).append("\");")
0626:                            .append(lineSeparator);
0627:
0628:                    beanCode.append("\t\t} else {").append(lineSeparator);
0629:
0630:                    if (create.equalsIgnoreCase("yes")) {
0631:                        // bean creation
0632:                        beanCode.append("\t\t\ttry {").append(lineSeparator);
0633:
0634:                        recordFileAndLineNr(beanCode);
0635:                        beanCode
0636:                                .append("\t\t\t\t")
0637:                                .append(varName)
0638:                                .append(" = (")
0639:                                .append(type)
0640:                                .append(") ")
0641:                                .append(
0642:                                        "java.beans.Beans.instantiate(this.getClass().getClassLoader(), \"")
0643:                                .append(beanName).append("\");").append(
0644:                                        lineSeparator);
0645:                        ;
0646:
0647:                        if (scope.equals("session")) {
0648:                            recordFileAndLineNr(beanCode);
0649:                            beanCode.append("\t\t\t\t__session.putValue(\"")
0650:                                    .append(javaStringEncode(name)).append(
0651:                                            "\", ").append(varName)
0652:                                    .append(");").append(lineSeparator);
0653:                        }
0654:
0655:                        beanCode
0656:                                .append(
0657:                                        "\t\t\t} catch(java.lang.ClassNotFoundException cnfexc) {")
0658:                                .append(lineSeparator);
0659:
0660:                        beanCode
0661:                                .append(
0662:                                        "\t\t\t\t__beanError(response, \"Could not create bean ")
0663:                                .append(javaStringEncode(name)).append(
0664:                                        " of type ").append(
0665:                                        javaStringEncode(type)).append(
0666:                                        " (class not found)\");").append(
0667:                                        lineSeparator);
0668:
0669:                        beanCode.append("\t\t\t\treturn;")
0670:                                .append(lineSeparator);
0671:
0672:                        beanCode.append("\t\t\t}").append(lineSeparator);
0673:                    } else {
0674:                        recordFileAndLineNr(beanCode);
0675:                        beanCode.append("\t\t\t__beanError(response, \"Bean ")
0676:                                .append(javaStringEncode(name)).append(
0677:                                        " does not exist or is not of type ")
0678:                                .append(javaStringEncode(type)).append("\");")
0679:                                .append(lineSeparator);
0680:
0681:                        beanCode.append("\t\t\treturn;");
0682:                    }
0683:
0684:                    beanCode.append("\t\t}").append(lineSeparator);
0685:
0686:                    if (beanDefaultProperties.size() > 0
0687:                            || introspect.equalsIgnoreCase("yes")) {
0688:                        beanCode.append("\t\ttry {").append(lineSeparator);
0689:
0690:                        recordFileAndLineNr(beanCode);
0691:                        beanCode
0692:                                .append(
0693:                                        "\t\t\t__propertyDescriptors = java.beans.Introspector.getBeanInfo(")
0694:                                .append(varName)
0695:                                .append(
0696:                                        ".getClass()).getPropertyDescriptors();")
0697:                                .append(lineSeparator);
0698:
0699:                        // set bean default properties
0700:                        e = beanDefaultProperties.keys();
0701:                        while (e.hasMoreElements()) {
0702:                            k = (String) e.nextElement();
0703:                            v = (String) beanDefaultProperties.get(k);
0704:
0705:                            recordFileAndLineNr(beanCode);
0706:                            beanCode.append("\t\t\tif(!__beanSetProperty(")
0707:                                    .append(varName).append(
0708:                                            ", __propertyDescriptors, \"")
0709:                                    .append(javaStringEncode(k)).append(
0710:                                            "\", \"").append(
0711:                                            javaStringEncode(v)).append(
0712:                                            "\")) {").append(lineSeparator);
0713:
0714:                            beanCode.append(
0715:                                    "\t\t\t\t__beanError(response, \"Bean ")
0716:                                    .append(javaStringEncode(name)).append(
0717:                                            " of type").append(
0718:                                            javaStringEncode(type)).append(
0719:                                            " has no property named ").append(
0720:                                            javaStringEncode(k)).append("\");")
0721:                                    .append(lineSeparator);
0722:
0723:                            beanCode.append("\t\t\t\treturn;").append(
0724:                                    lineSeparator);
0725:
0726:                            beanCode.append("\t\t\t}").append(lineSeparator);
0727:                        }
0728:
0729:                        // do bean introspection
0730:                        if (introspect.equalsIgnoreCase("yes")) {
0731:                            recordFileAndLineNr(beanCode);
0732:                            beanCode.append("\t\t\t__beanIntrospect(").append(
0733:                                    varName).append(
0734:                                    ", __propertyDescriptors, request);")
0735:                                    .append(lineSeparator);
0736:                        }
0737:
0738:                        beanCode
0739:                                .append(
0740:                                        "\t\t} catch(java.beans.IntrospectionException introexc) {")
0741:                                .append(lineSeparator);
0742:
0743:                        beanCode
0744:                                .append(
0745:                                        "\t\t\t__beanError(response, \"Introspection failed for bean ")
0746:                                .append(javaStringEncode(name)).append(
0747:                                        " of type ").append(
0748:                                        javaStringEncode(type)).append("\");")
0749:                                .append(lineSeparator);
0750:
0751:                        beanCode.append("\t\t}").append(lineSeparator);
0752:                    }
0753:                    beanCode.append(lineSeparator);
0754:                } finally {
0755:                    lineNr = endLineNr;
0756:                }
0757:            }
0758:
0759:            private String[] parseKeyAndValue()
0760:                    throws StringIndexOutOfBoundsException {
0761:                char c;
0762:                int pos;
0763:                String[] keyAndValue = new String[2];
0764:
0765:                // gather key
0766:                pos = srcPos;
0767:                for (;;) {
0768:                    c = src.charAt(srcPos);
0769:                    if (c == '=' || Character.isWhitespace(c)) {
0770:                        break;
0771:                    }
0772:                    srcPos++;
0773:                }
0774:                keyAndValue[0] = src.substring(pos, srcPos);
0775:                skipWhitespace();
0776:
0777:                // quick work around page processing
0778:                if ("page".equals(keyAndValue[0]))
0779:                    return parseKeyAndValue();
0780:
0781:                // gather optional value
0782:                if (src.charAt(srcPos) == '=') {
0783:                    srcPos++;
0784:                    skipWhitespace();
0785:
0786:                    c = src.charAt(srcPos);
0787:                    if (c == '\'' || c == '\"') {
0788:                        pos = src.indexOf(c, srcPos + 1);
0789:                        keyAndValue[1] = src.substring(srcPos + 1, pos);
0790:                        setSrcPos(pos + 1);
0791:                    } else {
0792:                        pos = srcPos;
0793:                        for (;;) {
0794:                            c = src.charAt(srcPos);
0795:                            if (c == '%' || c == '>'
0796:                                    || Character.isWhitespace(c)) {
0797:                                break;
0798:                            }
0799:                            srcPos++;
0800:                        }
0801:                        keyAndValue[1] = src.substring(pos, srcPos);
0802:                    }
0803:
0804:                    skipWhitespace();
0805:                } else {
0806:                    keyAndValue[1] = keyAndValue[0];
0807:                }
0808:
0809:                return keyAndValue;
0810:            }
0811:
0812:            private void changeParseState(int newState) {
0813:                if (newState == parseState)
0814:                    return;
0815:
0816:                switch (parseState) {
0817:                case PARSE_HTML:
0818:                    scriptletsCode.append("\");").append(lineSeparator);
0819:                    break;
0820:                case PARSE_EXPRESSION:
0821:                    scriptletsCode.append("));").append(lineSeparator);
0822:                    break;
0823:                case PARSE_DECLARATION:
0824:                    declarationsCode.append(lineSeparator);
0825:                    break;
0826:                case PARSE_SCRIPTLET:
0827:                    scriptletsCode.append(lineSeparator);
0828:                    break;
0829:                }
0830:
0831:                parseState = newState;
0832:
0833:                switch (parseState) {
0834:                case PARSE_HTML:
0835:                    recordFileAndLineNr(scriptletsCode);
0836:                    scriptletsCode.append("\t\t\tout.print(\"");
0837:                    break;
0838:                case PARSE_EXPRESSION:
0839:                    recordFileAndLineNr(scriptletsCode);
0840:                    scriptletsCode.append("\t\t\tout.print(__valueOf(");
0841:                    break;
0842:                case PARSE_DECLARATION:
0843:                    recordFileAndLineNr(declarationsCode);
0844:                    break;
0845:                case PARSE_SCRIPTLET:
0846:                    recordFileAndLineNr(scriptletsCode);
0847:                    break;
0848:                }
0849:            }
0850:
0851:            private void recordFileAndLineNr(StringBuffer code) {
0852:                // FIXME: do nice encoding of backslashes in filename
0853:                code.append(
0854:                        "//line " + jspFile.toString().replace('\\', '/') + ":"
0855:                                + lineNr).append(lineSeparator);
0856:            }
0857:
0858:            private void skipWhitespace() {
0859:                char c;
0860:
0861:                for (;;) {
0862:                    c = src.charAt(srcPos);
0863:                    if (!Character.isWhitespace(c)) {
0864:                        break;
0865:                    } else if (c == '\n') {
0866:                        lineNr++;
0867:                    }
0868:                    srcPos++;
0869:                }
0870:            }
0871:
0872:            private void setSrcPos(int newSrcPos) {
0873:                int from;
0874:
0875:                if (newSrcPos < 0 || newSrcPos >= src.length())
0876:                    throw new StringIndexOutOfBoundsException(Integer
0877:                            .toString(newSrcPos));
0878:
0879:                from = srcPos - 1;
0880:                for (;;) {
0881:                    from = src.indexOf('\n', from + 1);
0882:                    if (from == -1 || from >= newSrcPos) {
0883:                        break;
0884:                    }
0885:                    lineNr++;
0886:                }
0887:                srcPos = newSrcPos;
0888:            }
0889:
0890:            private void generateJavaFile() throws JSPException {
0891:                PrintWriter out;
0892:                Enumeration e;
0893:                File f;
0894:                String pn, cn;
0895:                Long l;
0896:                int i;
0897:
0898:                try {
0899:                    f = new File(javaFile.getParent());
0900:                    f.mkdirs();
0901:                    out = new PrintWriter(new FileWriter(javaFile));
0902:                    i = className.lastIndexOf('.');
0903:                    if (i > 0) {
0904:                        pn = className.substring(0, i);
0905:                        cn = className.substring(i + 1);
0906:                    } else {
0907:                        pn = null;
0908:                        cn = className;
0909:                    }
0910:                    try {
0911:                        // generate header and start of class
0912:                        out
0913:                                .println("/* Automatically generated by GNUJSP. Do not edit. */");
0914:                        if (pn != null) {
0915:                            out.println("package " + pn + ";");
0916:                        }
0917:                        out.println(importDirective);
0918:                        out.println("public final class " + cn + " extends "
0919:                                + extendsDirective + implements Directive);
0920:                        out.println("{");
0921:
0922:                        // generate declarations
0923:                        out.println(declarationsCode);
0924:
0925:                        // generate specified method
0926:                        out
0927:                                .println("\tpublic void "
0928:                                        + methodDirective
0929:                                        + "(javax.servlet.http.HttpServletRequest request, "
0930:                                        + "javax.servlet.http.HttpServletResponse response) "
0931:                                        + "throws javax.servlet.ServletException, java.io.IOException");
0932:                        out.println("\t{");
0933:                        if (createSession) {
0934:                            out
0935:                                    .println("\t\tjavax.servlet.http.HttpSession __session = request.getSession(true);");
0936:                        }
0937:                        out.println(beanCode);
0938:                        out.println("\t\tresponse.setContentType(\""
0939:                                + javaStringEncode(content_typeDirective)
0940:                                + "\");");
0941:                        out
0942:                                .println("\t\tjava.io.PrintWriter out = response.getWriter();");
0943:                        out.println("\t\ttry {");
0944:                        out.println(scriptletsCode);
0945:                        out.println("\t\t} finally {");
0946:                        out.println("\t\t\tout.flush();");
0947:                        out.println("\t\t\tout.close();");
0948:                        out.println("\t\t}");
0949:                        out.println("\t}");
0950:                        out.println();
0951:
0952:                        // generate own version of String.valueOf()
0953:                        out
0954:                                .println("\tprivate static java.lang.String __valueOf(java.lang.Object obj) {");
0955:                        out.println("\t\tif(obj == null) {");
0956:                        out.println("\t\t\treturn \"\";");
0957:                        out.println("\t\t} else {");
0958:                        out.println("\t\t\treturn obj.toString();");
0959:                        out.println("\t\t}");
0960:                        out.println("\t}");
0961:                        out
0962:                                .println("\tprivate static java.lang.String __valueOf(boolean b) { return java.lang.String.valueOf(b); }");
0963:                        out
0964:                                .println("\tprivate static java.lang.String __valueOf(char c)    { return java.lang.String.valueOf(c); }");
0965:                        out
0966:                                .println("\tprivate static java.lang.String __valueOf(int i)     { return java.lang.String.valueOf(i); }");
0967:                        out
0968:                                .println("\tprivate static java.lang.String __valueOf(long l)    { return java.lang.String.valueOf(l); }");
0969:                        out
0970:                                .println("\tprivate static java.lang.String __valueOf(float f)   { return java.lang.String.valueOf(f); }");
0971:                        out
0972:                                .println("\tprivate static java.lang.String __valueOf(double d)  { return java.lang.String.valueOf(d); }");
0973:                        out.println();
0974:
0975:                        // generate bean functions
0976:                        out
0977:                                .println("\tprivate void __beanError(javax.servlet.http.HttpServletResponse response, java.lang.String msg) throws java.io.IOException {");
0978:                        out
0979:                                .println("\t\tresponse.setStatus(javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR, \"JSP run-time error\");");
0980:                        out
0981:                                .println("\t\tresponse.setContentType(\"text/html\");");
0982:                        out
0983:                                .println("\t\tjava.io.PrintWriter errOut = response.getWriter();");
0984:                        out
0985:                                .println("\t\terrOut.println(\"<HTML><HEAD><TITLE>\" + javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR + \" JSP run-time error</TITLE></HEAD><BODY>\" +");
0986:                        out
0987:                                .println("\t\t\t\"<H2>\" + javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR + \" JSP run-time error</H2>\" +");
0988:                        out
0989:                                .println("\t\t\t\"The JSP page you requested could not be served because the following error(s) occured:<BR><PRE>\");");
0990:                        out.println("\t\terrOut.println(msg);");
0991:                        out
0992:                                .println("\t\terrOut.println(\"</PRE></BODY></HTML>\");");
0993:                        out.println("\t\terrOut.close();");
0994:                        out.println("\t}");
0995:                        out.println();
0996:
0997:                        out
0998:                                .println("\tprivate boolean __beanSetProperty(java.lang.Object bean, java.beans.PropertyDescriptor[] pds, java.lang.String key, java.lang.String value) {");
0999:                        out.println("\t\tjava.lang.reflect.Method meth;");
1000:                        out
1001:                                .println("\t\tfor(int i = 0; i < pds.length; i++) {");
1002:                        out
1003:                                .println("\t\t\tif(pds[i].getName().equals(key) && !pds[i].isHidden()) {");
1004:                        out.println("\t\t\t\tmeth = pds[i].getWriteMethod();");
1005:                        out.println("\t\t\t\tif(meth != null) {");
1006:                        out.println("\t\t\t\t\ttry {");
1007:                        out
1008:                                .println("\t\t\t\t\t\tmeth.invoke(bean, new Object[]{value});");
1009:                        out.println("\t\t\t\t\t\treturn true;");
1010:                        out
1011:                                .println("\t\t\t\t\t} catch(java.lang.IllegalAccessException iaccexc) {");
1012:                        out.println("\t\t\t\t\t\treturn false;");
1013:                        out
1014:                                .println("\t\t\t\t\t} catch(java.lang.IllegalArgumentException iargexc) {");
1015:                        out.println("\t\t\t\t\t\treturn false;");
1016:                        out
1017:                                .println("\t\t\t\t\t} catch(java.lang.reflect.InvocationTargetException itexc) {");
1018:                        out.println("\t\t\t\t\t\treturn false;");
1019:                        out.println("\t\t\t\t\t}");
1020:                        out.println("\t\t\t\t}");
1021:                        out.println("\t\t\t}");
1022:                        out.println("\t\t}");
1023:                        out.println("\t\treturn false;");
1024:                        out.println("\t}");
1025:                        out.println();
1026:
1027:                        out
1028:                                .println("\tprivate void __beanIntrospect(java.lang.Object bean, java.beans.PropertyDescriptor[] pds, javax.servlet.http.HttpServletRequest request) {");
1029:                        out.println("\t\tjava.lang.reflect.Method meth;");
1030:                        out.println("\t\tjava.lang.String value;");
1031:                        out
1032:                                .println("\t\tfor(int i = 0; i < pds.length; i++) {");
1033:                        out.println("\t\t\tif(!pds[i].isHidden()) {");
1034:                        out
1035:                                .println("\t\t\t\tvalue = request.getParameter(pds[i].getName());");
1036:                        out.println("\t\t\t\tif(value != null) {");
1037:                        out
1038:                                .println("\t\t\t\t\tmeth = pds[i].getWriteMethod();");
1039:                        out.println("\t\t\t\t\tif(meth != null) {");
1040:                        out.println("\t\t\t\t\t\ttry {");
1041:                        out
1042:                                .println("\t\t\t\t\t\t\tmeth.invoke(bean, new Object[]{value});");
1043:                        out
1044:                                .println("\t\t\t\t\t\t} catch(java.lang.IllegalAccessException iaccexc) {");
1045:                        out.println("\t\t\t\t\t\t\t//");
1046:                        out
1047:                                .println("\t\t\t\t\t\t} catch(java.lang.IllegalArgumentException iargexc) {");
1048:                        out.println("\t\t\t\t\t\t\t//");
1049:                        out
1050:                                .println("\t\t\t\t\t\t} catch(java.lang.reflect.InvocationTargetException itexc) {");
1051:                        out.println("\t\t\t\t\t\t\t//");
1052:                        out.println("\t\t\t\t\t\t}");
1053:                        out.println("\t\t\t\t\t}");
1054:                        out.println("\t\t\t\t}");
1055:                        out.println("\t\t\t}");
1056:                        out.println("\t\t}");
1057:                        out.println("\t}");
1058:                        out.println();
1059:
1060:                        // generate dependency check code
1061:                        out
1062:                                .println("\tpublic static final int __compilerVersionNr = "
1063:                                        + COMPILER_VERSION_NR + ";");
1064:                        out.println();
1065:
1066:                        out
1067:                                .println("\tprivate static java.lang.Object[] __dependencies = new java.lang.Object[]{");
1068:                        e = dependencies.elements();
1069:                        for (;;) {
1070:                            f = (File) e.nextElement();
1071:                            l = (Long) e.nextElement();
1072:                            out.println("\t\tnew java.io.File(\""
1073:                                    + javaStringEncode(f.toString()) + "\"),");
1074:                            out.print("\t\tnew java.lang.Long(" + l + "L)");
1075:                            if (e.hasMoreElements()) {
1076:                                out.println(",");
1077:                            } else {
1078:                                out.println();
1079:                                break;
1080:                            }
1081:                        }
1082:                        out.println("\t};");
1083:                        out.println();
1084:
1085:                        out
1086:                                .println("\tpublic static boolean __checkDependencies() {");
1087:                        out
1088:                                .println("\t\tfor(int i = 0; i < __dependencies.length; i += 2) {");
1089:                        out
1090:                                .println("\t\t\tif(!((java.io.File) __dependencies[i]).exists() ||");
1091:                        out
1092:                                .println("\t\t\t\t\t((java.io.File) __dependencies[i]).lastModified() > ((java.lang.Long) __dependencies[i+1]).longValue()) {");
1093:                        out.println("\t\t\t\treturn true;");
1094:                        out.println("\t\t\t}");
1095:                        out.println("\t\t}");
1096:                        out.println("\t\treturn false;");
1097:                        out.println("\t}");
1098:
1099:                        // generate end of class
1100:                        out.println("}");
1101:                    } finally {
1102:                        out.close();
1103:                    }
1104:                } catch (IOException ioexc) {
1105:                    throw new JSPException("Could not write java file "
1106:                            + javaFile + ": " + ioexc.getMessage());
1107:                }
1108:            }
1109:
1110:            private void compileJavaFile() throws JSPException {
1111:                String[] compilerArgs;
1112:                ByteArrayOutputStream compilerOut;
1113:                PrintStream compilerOutStream;
1114:                String s, t;
1115:                StringBuffer buf;
1116:                int i, j, k, l;
1117:
1118:                compilerOut = new ByteArrayOutputStream();
1119:                compilerOutStream = new PrintStream(compilerOut, true);
1120:
1121:                // build compiler command line
1122:                if (jspServlet.compiler[0].equals("builtin-javac")) {
1123:                    compilerArgs = new String[jspServlet.compiler.length - 1];
1124:                    j = 0;
1125:                } else {
1126:                    compilerArgs = new String[jspServlet.compiler.length];
1127:                    compilerArgs[0] = jspServlet.compiler[0];
1128:                    j = 1;
1129:                }
1130:                compilerOutStream.print(jspServlet.compiler[0]);
1131:
1132:                for (i = 1; i < jspServlet.compiler.length; i++) {
1133:                    s = jspServlet.compiler[i];
1134:                    buf = new StringBuffer(s.length() + 16);
1135:                    k = s.indexOf('%');
1136:                    l = -1;
1137:                    while (k != -1) {
1138:                        buf.append(s.substring(l + 1, k));
1139:                        l = s.indexOf('%', k + 1);
1140:                        if (l == -1) {
1141:                            l = k - 1;
1142:                            break;
1143:                        } else {
1144:                            t = s.substring(k + 1, l);
1145:                            if (t.length() == 0) {
1146:                                t = "%";
1147:                            } else if (t.equalsIgnoreCase("classpath")) {
1148:                                t = Utils.calculateClassPath(getClass()
1149:                                        .getClassLoader());
1150:                            } else if (t.equalsIgnoreCase("repository")) {
1151:                                t = jspServlet.repository.toString();
1152:                            } else if (t.equalsIgnoreCase("source")) {
1153:                                t = javaFile.toString();
1154:                            } else {
1155:                                t = jspServlet.getServletConfig()
1156:                                        .getInitParameter(t);
1157:                            }
1158:
1159:                            if (t != null) {
1160:                                buf.append(t);
1161:                            }
1162:                            k = s.indexOf('%', l + 1);
1163:                        }
1164:                    }
1165:                    buf.append(s.substring(l + 1));
1166:                    compilerArgs[j] = buf.toString();
1167:                    compilerOutStream.print((char) ' ');
1168:                    compilerOutStream.print(compilerArgs[j]);
1169:                    j++;
1170:                }
1171:                compilerOutStream.println();
1172:
1173:                if (jspServlet.compiler[0].equals("builtin-javac")) {
1174:                    // use builtin compiler
1175:                    try {
1176:                        Object javaCompiler = Class.forName(
1177:                                "sun.tools.javac.Main")
1178:                                .getConstructor(
1179:                                        new Class[] { OutputStream.class,
1180:                                                String.class }).newInstance(
1181:                                        new Object[] { compilerOutStream,
1182:                                                "javac" });
1183:                        if (Boolean.FALSE.equals(javaCompiler.getClass()
1184:                                .getMethod("compile",
1185:                                        new Class[] { String[].class }).invoke(
1186:                                        javaCompiler,
1187:                                        new Object[] { compilerArgs }))) {
1188:                            throw new JSPException(
1189:                                    transcribeErrors(htmlEncode(compilerOut
1190:                                            .toString())));
1191:                        }
1192:                    } catch (Exception e) {
1193:                        if (e instanceof  JSPException)
1194:                            throw (JSPException) e;
1195:                        throw new JSPException(
1196:                                transcribeErrors(htmlEncode("Can't instantiate Java compiler, "
1197:                                        + e + "/" + e.getCause())));
1198:                    }
1199:                } else {
1200:                    // use external compiler
1201:                    Process p;
1202:                    BufferedReader stdout = null, stderr = null;
1203:                    String line;
1204:                    int exitValue = -1;
1205:                    long classLastModified;
1206:
1207:                    classLastModified = classFile.lastModified();
1208:
1209:                    try {
1210:                        p = Runtime.getRuntime().exec(compilerArgs);
1211:                        stdout = new BufferedReader(new InputStreamReader(p
1212:                                .getInputStream()));
1213:                        stderr = new BufferedReader(new InputStreamReader(p
1214:                                .getErrorStream()));
1215:                        // polling should be threaded
1216:                        while ((line = stdout.readLine()) != null) {
1217:                            compilerOutStream.println(line);
1218:                        }
1219:
1220:                        while ((line = stderr.readLine()) != null) {
1221:                            compilerOutStream.println(line);
1222:                        }
1223:
1224:                        try {
1225:                            p.waitFor();
1226:                            exitValue = p.exitValue();
1227:                        } catch (InterruptedException ix) {
1228:                            ;
1229:                        }
1230:                    } catch (IOException ioexc) {
1231:                        ioexc.printStackTrace(compilerOutStream);
1232:                    }
1233:
1234:                    if (classFile.lastModified() == classLastModified) {
1235:                        compilerOutStream
1236:                                .println("[no class file has been written]");
1237:                        exitValue = -1;
1238:                    }
1239:
1240:                    if (exitValue != 0) {
1241:                        throw new JSPException(
1242:                                transcribeErrors(htmlEncode(compilerOut
1243:                                        .toString())));
1244:                    }
1245:                }
1246:            }
1247:
1248:            private static String htmlEncode(String val) {
1249:                StringBuffer buf = new StringBuffer(val.length() + 8);
1250:                char c;
1251:
1252:                for (int i = 0; i < val.length(); i++) {
1253:                    c = val.charAt(i);
1254:                    switch (c) {
1255:                    case '<':
1256:                        buf.append("&lt;");
1257:                        break;
1258:                    case '>':
1259:                        buf.append("&gt;");
1260:                        break;
1261:                    case '&':
1262:                        buf.append("&amp;");
1263:                        break;
1264:                    default:
1265:                        buf.append(c);
1266:                        break;
1267:                    }
1268:                }
1269:                return buf.toString();
1270:            }
1271:
1272:            private static class MapEntry {
1273:                int javaLineNr;
1274:                String jspFile;
1275:                int jspLineNr;
1276:
1277:                MapEntry(int javaLineNr, String jspFile, int jspLineNr) {
1278:                    this .javaLineNr = javaLineNr;
1279:                    this .jspFile = jspFile;
1280:                    this .jspLineNr = jspLineNr;
1281:                }
1282:            }
1283:
1284:            /**
1285:             * Transcribe error messages
1286:             */
1287:            private String transcribeErrors(String errors) {
1288:                LineNumberReader in;
1289:                BufferedReader in2;
1290:                Vector map;
1291:                Enumeration e;
1292:                MapEntry entry;
1293:                StringBuffer errBuf;
1294:                String s, jspFile;
1295:                int i, j, k, l, javaLineNr, jspLineNr;
1296:
1297:                try {
1298:                    /* Build mapping from java line numbers to jsp file/line# combinations.
1299:                     * We could have done this will writing the java file, but using
1300:                     * LineNumberReader is easier, and it would take extra time when
1301:                     * no errors occur.
1302:                     */
1303:                    in = new LineNumberReader(new FileReader(javaFile));
1304:                    in.setLineNumber(1);
1305:                    map = new Vector();
1306:                    try {
1307:                        while ((s = in.readLine()) != null) {
1308:                            if (s.startsWith("//line ")) {
1309:                                i = s.indexOf(':');
1310:                                if (i >= 0) {
1311:                                    try {
1312:                                        map.addElement(new MapEntry(in
1313:                                                .getLineNumber(), s.substring(
1314:                                                7, i), Integer.parseInt(s
1315:                                                .substring(i + 1))));
1316:                                    } catch (NumberFormatException nfexc) {
1317:                                    }
1318:                                }
1319:                            }
1320:                        }
1321:                    } finally {
1322:                        in.close();
1323:                    }
1324:
1325:                    /* Now we read every line of the error messages and translate any
1326:                     * file references there.
1327:                     */
1328:                    in2 = new BufferedReader(new StringReader(errors));
1329:                    errBuf = new StringBuffer();
1330:                    try {
1331:                        while ((s = in2.readLine()) != null) {
1332:                            i = s.indexOf(javaFile.getPath());
1333:                            if (i != -1) {
1334:                                j = i + javaFile.getPath().length();
1335:                                if (j < s.length() - 1 && s.charAt(j) == ':'
1336:                                        && Character.isDigit(s.charAt(j + 1))) {
1337:                                    j++;
1338:                                    k = j;
1339:                                    while (k < s.length()
1340:                                            && Character.isDigit(s.charAt(k))) {
1341:                                        k++;
1342:                                    }
1343:                                    l = k;
1344:                                    while (l + 1 < s.length()
1345:                                            && s.charAt(l) == ':'
1346:                                            && Character.isDigit(s
1347:                                                    .charAt(l + 1))) {
1348:                                        l += 2;
1349:                                        while (l < s.length()
1350:                                                && Character.isDigit(s
1351:                                                        .charAt(l))) {
1352:                                            l++;
1353:                                        }
1354:                                    }
1355:
1356:                                    try {
1357:                                        javaLineNr = Integer.parseInt(s
1358:                                                .substring(j, k));
1359:                                        jspFile = null;
1360:                                        jspLineNr = 0;
1361:                                        for (e = map.elements(); e
1362:                                                .hasMoreElements();) {
1363:                                            entry = (MapEntry) e.nextElement();
1364:                                            if (entry.javaLineNr > javaLineNr) {
1365:                                                break;
1366:                                            }
1367:                                            jspFile = entry.jspFile;
1368:                                            jspLineNr = entry.jspLineNr
1369:                                                    + (javaLineNr - entry.javaLineNr);
1370:                                        }
1371:                                        // valid translation found: use it
1372:                                        if (jspFile != null) {
1373:                                            errBuf.append(s.substring(0, i));
1374:                                            errBuf.append("<B>")
1375:                                                    .append(jspFile).append(
1376:                                                            (char) ':').append(
1377:                                                            jspLineNr).append(
1378:                                                            "</B>");
1379:                                            errBuf.append("<!-- ").append(
1380:                                                    s.substring(i, l)).append(
1381:                                                    " -->");
1382:                                            errBuf.append(s.substring(l))
1383:                                                    .append(lineSeparator);
1384:                                            continue;
1385:                                        }
1386:                                    } catch (NumberFormatException nfexc2) {
1387:                                    }
1388:                                }
1389:                            }
1390:                            errBuf.append(s).append(lineSeparator);
1391:                        }
1392:                        return errBuf.toString();
1393:                    } finally {
1394:                        in2.close();
1395:                    }
1396:                } catch (IOException ioexc) {
1397:                    return errors;
1398:                }
1399:            }
1400:
1401:            private static String javaStringEncode(String val) {
1402:                StringBuffer res;
1403:                String s;
1404:                int i;
1405:                char c;
1406:
1407:                res = new StringBuffer(val.length());
1408:                for (i = 0; i < val.length(); i++) {
1409:                    c = val.charAt(i);
1410:                    switch (c) {
1411:                    case '\n':
1412:                        res.append("\\n");
1413:                        break;
1414:                    case '\r':
1415:                        res.append("\\r");
1416:                        break;
1417:                    case '\'':
1418:                        res.append("\\\'");
1419:                        break;
1420:                    case '\"':
1421:                        res.append("\\\"");
1422:                        break;
1423:                    case '\\':
1424:                        res.append("\\\\");
1425:                        break;
1426:                    default:
1427:                        if (c > 0xFF) {
1428:                            s = "00" + Integer.toHexString(c);
1429:                            res.append("\\u").append(
1430:                                    s.substring(s.length() - 4));
1431:                        } else if (c < ' ' || c >= 0x7F) {
1432:                            s = "00" + Integer.toOctalString(c);
1433:                            res.append((char) '\\').append(
1434:                                    s.substring(s.length() - 3));
1435:                        } else {
1436:                            res.append((char) c);
1437:                        }
1438:                        break;
1439:                    }
1440:                }
1441:                return res.toString();
1442:            }
1443:
1444:            public static String getClassNameForJspFile(File jspFile)
1445:                    throws JSPException {
1446:                StringTokenizer toker;
1447:                StringBuffer buf;
1448:                String s = jspFile.toString();
1449:                char c;
1450:                int i;
1451:
1452:                toker = new StringTokenizer(s, String
1453:                        .valueOf(File.separatorChar));
1454:                buf = new StringBuffer(s.length() + 32);
1455:                buf.append("_jsp");
1456:                while (toker.hasMoreTokens()) {
1457:                    s = toker.nextToken();
1458:                    buf.append("._");
1459:                    for (i = 0; i < s.length(); i++) {
1460:                        c = s.charAt(i);
1461:                        if (Character.isJavaIdentifierPart(c)) {
1462:                            buf.append((char) c);
1463:                        } else {
1464:                            buf.append((char) '_').append(
1465:                                    Integer.toHexString(c));
1466:                        }
1467:                    }
1468:                }
1469:
1470:                return buf.toString();
1471:            }
1472:
1473:            public static File getFileForClass(File repository,
1474:                    String className, String suffix) {
1475:                return new File(repository, className.replace('.',
1476:                        File.separatorChar)
1477:                        + suffix);
1478:            }
1479:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.