0001: //** Copyright Statement ***************************************************
0002: //The Salmon Open Framework for Internet Applications (SOFIA)
0003: // Copyright (C) 1999 - 2002, Salmon LLC
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 version 2
0007: // as published by the Free Software Foundation;
0008: //
0009: // This program is distributed in the hope that it will be useful,
0010: // but WITHOUT ANY WARRANTY; without even the implied warranty of
0011: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0012: // GNU General Public License for more details.
0013: //
0014: // You should have received a copy of the GNU General Public License
0015: // along with this program; if not, write to the Free Software
0016: // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
0017: //
0018: // For more information please visit http://www.salmonllc.com
0019: //** End Copyright Statement ***************************************************
0020: package com.salmonllc.jsp.engine;
0021:
0022: /////////////////////////
0023: //$Archive: /SOFIA/SourceCode/com/salmonllc/jsp/engine/JspConverter.java $
0024: //$Author: Srufle $
0025: //$Revision: 45 $
0026: //$Modtime: 10/26/04 3:54p $
0027: /////////////////////////
0028: import java.util.*;
0029: import java.io.*;
0030:
0031: import com.salmonllc.util.*;
0032: import com.salmonllc.properties.*;
0033: import javax.servlet.jsp.tagext.*;
0034: import javax.servlet.*;
0035: import javax.servlet.http.HttpServletResponse;
0036: import javax.servlet.http.HttpSession;
0037: import javax.servlet.http.HttpServletRequest;
0038: import javax.servlet.jsp.*;
0039: import java.lang.reflect.*;
0040: import com.salmonllc.jsp.tags.*;
0041: import com.salmonllc.jsp.*;
0042: import com.salmonllc.sql.*;
0043: import com.salmonllc.localizer.LanguagePreferences;
0044: import com.salmonllc.html.HtmlPageBase;
0045: import com.salmonllc.html.HttpServletResponseDummy;
0046:
0047: /**
0048: * This class can be used to process a simple JSP page and transform it into
0049: * the HTML that will be displayed when the page will be run by a JSP Engine.
0050: * It only implements the Custom Tag portion of the JSP spec. Other JSP tags will
0051: * be left as they are.
0052: * The converter has two flavors of output:
0053: * HTML: convert the page to standard HTML
0054: * DREAMWEAVER: convert the page to DreamWeaver HTML (custom tags are wrapped in <MMBeginLock> <MMEndLock> tags)
0055: */
0056:
0057: public class JspConverter {
0058: public static final int CONV_HTML = 0;
0059: public static final int CONV_DREAMWEAVER = 1;
0060:
0061: private static final int MODE_TEXT = 0;
0062: private static final int MODE_TAG = 1;
0063: private static final int MODE_SCRIPT = 2;
0064: private static final int MODE_COMMENT = 3;
0065:
0066: private static final int TYPE_UNQUOTED = 0;
0067: private static final int TYPE_QUOTED = 1;
0068: private static final int TYPE_EQUALS = 2;
0069: private static final int TYPE_START_TAG = 3;
0070: private static final int TYPE_END_TAG = 4;
0071: private static final int TYPE_SLASH = 5;
0072: private static final int TYPE_ERROR = 6;
0073:
0074: private int _convType;
0075:
0076: private JspDocument _doc;
0077: private JspElement _bodyTag;
0078: private JspElement _endBodyTag;
0079: private JspElement _pageTag;
0080: private JspElement _endPageTag;
0081: private boolean _pageTagAdded;
0082: private String _app = "default";
0083: private Servlet _servlet;
0084: private ServletRequest _req;
0085: private ServletResponse _res;
0086: private HttpSession _sess;
0087:
0088: private Vector _tagLibs = new Vector(2);
0089:
0090: private Vector _tagAttributes = new Vector();
0091: private StringBuffer _nextTag = new StringBuffer();
0092: private StringBuffer _nextText = new StringBuffer();
0093: private StringBuffer _nextTagName = new StringBuffer();
0094: private StringBuffer _nextTagPrefix = new StringBuffer();
0095:
0096: private boolean _tagNameStarted;
0097: private boolean _tagNameEnded;
0098: private boolean _tagPrefixEnded;
0099: private int _tagNamePos;
0100:
0101: private StringBuffer _nextToken = new StringBuffer();
0102: private int _nextTokenIndex = 0;
0103: private char _quote = ' ';
0104:
0105: private int _mode = MODE_TEXT;
0106:
0107: private int _inSize = 0;
0108: private String _page;
0109: private int _inPos = 0;
0110: private InputStream _in;
0111: private FileOutputStream _debugOut;
0112: private int _iRet = 0;
0113: private boolean _handleIncludes = false;
0114: private String _documentBase = null;
0115:
0116: private Stack _st = new Stack();
0117: private int _errorCount = 0;
0118:
0119: private static Class[] STRING_PARM = { new String().getClass() };
0120:
0121: private Hashtable _tagNames = new Hashtable();
0122:
0123: private static Hashtable _tagMap = new Hashtable();
0124: private static Boolean ok = new Boolean(true);
0125: private StringBuffer _nestTest = new StringBuffer();
0126:
0127: static {
0128: _tagMap.put("datatable-*", ok);
0129: _tagMap.put("*-datatableheader", ok);
0130: _tagMap.put("*-datatablefooter", ok);
0131: _tagMap.put("*-datatablegroupheader", ok);
0132: _tagMap.put("*-datatablegroupfooter", ok);
0133: _tagMap.put("*-datatablerows", ok);
0134: _tagMap.put("*-tr", ok);
0135: _tagMap.put("*-td", ok);
0136: _tagMap.put("displaybox-*", ok);
0137: _tagMap.put("*-displayboxheader", ok);
0138: _tagMap.put("*-displayboxcontents", ok);
0139: _tagMap.put("*-option", ok);
0140: _tagMap.put("input-*", ok);
0141: _tagMap.put("*-navbargroup", ok);
0142: _tagMap.put("*-navbaritem", ok);
0143: _tagMap.put("*-navbarsubitem", ok);
0144: _tagMap.put("navbar-*", ok);
0145:
0146: _tagMap.put("datatable-datatableheader", ok);
0147: _tagMap.put("datatable-datatablefooter", ok);
0148: _tagMap.put("datatable-datatablegroupheader", ok);
0149: _tagMap.put("datatable-datatablegroupfooter", ok);
0150: _tagMap.put("datatable-datatablerows", ok);
0151:
0152: _tagMap.put("datatableheader-tr", ok);
0153: _tagMap.put("datatablefooter-tr", ok);
0154: _tagMap.put("datatablegroupheader-tr", ok);
0155: _tagMap.put("datatablegroupfooter-tr", ok);
0156: _tagMap.put("datatablerows-tr", ok);
0157: _tagMap.put("table-tr", ok);
0158:
0159: _tagMap.put("displaybox-displayboxheader", ok);
0160: _tagMap.put("displaybox-displayboxcontents", ok);
0161:
0162: _tagMap.put("input-option", ok);
0163:
0164: _tagMap.put("tr-td", ok);
0165:
0166: _tagMap.put("navbar-navbargroup", ok);
0167: _tagMap.put("navbar-navbaritem", ok);
0168: _tagMap.put("navbar-navbarsubitem", ok);
0169: }
0170:
0171: private JspConverter(InputStream in, Servlet serv,
0172: ServletRequest req, ServletResponse res, int convType,
0173: String docBase) throws IOException {
0174: _servlet = serv;
0175: _req = req;
0176: _res = res;
0177: _in = in;
0178: _sess = ((HttpServletRequest) _req).getSession(true);
0179: _convType = convType;
0180: if (docBase != null)
0181: setHandleIncludes(docBase);
0182: Props p = Props.getSystemProps();
0183: String fileName = p
0184: .getProperty(Props.JSP_ENGINE_DEBUG_INPUT_FILE);
0185: if (fileName != null)
0186: _debugOut = new FileOutputStream(fileName);
0187:
0188: _inSize = req.getContentLength();
0189: if (_inSize == -1)
0190: _inSize = in.available();
0191: byte[] buffer = new byte[_inSize];
0192: try {
0193: int offset = 0;
0194: int len = 0;
0195: while ((_inSize - offset) > 0) {
0196: len = in.read(buffer, offset, _inSize - offset);
0197: if (len <= 0)
0198: throw new IOException();
0199: offset += len;
0200: }
0201:
0202: } catch (IOException e) {
0203: }
0204:
0205: String lang;
0206: if (_inSize > 0 && buffer[0] == '*') {
0207: int endPos = 1;
0208: for (; endPos < _inSize && buffer[endPos] != '*'; endPos++)
0209: ;
0210: if (endPos > 1) {
0211: String header = new String(buffer, 1, endPos - 1);
0212: StringTokenizer st = new StringTokenizer(header, ",");
0213: if (st.hasMoreTokens())
0214: _app = st.nextToken();
0215: if (st.hasMoreTokens()) {
0216: lang = st.nextToken();
0217:
0218: LanguagePreferences langPref = new LanguagePreferences(
0219: lang);
0220: if (_sess != null)
0221: _sess.setAttribute(
0222: HtmlPageBase.LANGUAGE_SESSION_KEY,
0223: langPref);
0224:
0225: }
0226: }
0227: try {
0228: String tmpStr = new String(buffer, endPos + 1, _inSize
0229: - endPos - 1, "UTF-8");
0230: _page = tmpStr;
0231: } catch (UnsupportedEncodingException e1) {
0232: _page = new String(buffer, endPos + 1, _inSize - endPos
0233: - 1);
0234: }
0235: } else {
0236: _page = new String(buffer, 0, _inSize);
0237: }
0238:
0239: if (_debugOut != null)
0240: _debugOut.write(buffer);
0241:
0242: _inSize = _page.length();
0243:
0244: }
0245:
0246: private int checkTagType(TagSupport handler, int defaultType) {
0247: if (_convType == CONV_HTML)
0248: return defaultType;
0249:
0250: if (handler instanceof BaseEmptyTag) {
0251: if (((BaseEmptyTag) handler).getTagConvertType() == BaseEmptyTag.CONV_DONT_CONVERT)
0252: return JspElement.TAG_HTML;
0253: }
0254:
0255: if (handler instanceof BaseBodyTag) {
0256: if (((BaseBodyTag) handler).getTagConvertType() == BaseBodyTag.CONV_DONT_CONVERT)
0257: return JspElement.TAG_HTML;
0258: }
0259:
0260: return defaultType;
0261: }
0262:
0263: /**
0264: * This method will convert the document and send the results to the servlet output stream.
0265: * If the properties: JSPEngineDebugOutputFile and JSPEngineDebugInputFile properties are specified
0266: * in the system.properties file, the input (from the servlet input stream) and output will
0267: * also be written to those files as well.
0268: * This method must be called from a doGet, doPost or service method of a servlet.
0269: * @param in java.io.InputStream The stream containing the JSP to process
0270: * @param serv javax.servlet.Servlet The servlet that is running this method.
0271: * @param req javax.servlet.ServletRequest The request for the servlet running this method.
0272: * @param res javax.servlet.ServletResponse The response for the servlet running this method.
0273: * @param convType int valid values are: CONV_HTML: convert the page to standard HTML<BR> or CONV_DREAMWEAVER: convert the page to DreamWeaver HTML (custom tags are wrapped in <MMBeginLock> <MMEndLock> tags).
0274: */
0275: public static void convertDocument(InputStream in, Servlet serv,
0276: ServletRequest req, ServletResponse res, int convType)
0277: throws java.lang.Exception {
0278: JspConverter con = new JspConverter(in, serv, req, res,
0279: convType, null);
0280: con.processDocument();
0281: }
0282:
0283: /**
0284: * This method will convert the document and generate instance variables for it.
0285: * If the properties: JSPEngineDebugOutputFile and JSPEngineDebugInputFile properties are specified
0286: * in the system.properties file, the input (from the servlet input stream) and output will
0287: * also be written to those files as well.
0288: * This method must be called from a doGet, doPost or service method of a servlet.
0289: * @param in java.io.InputStream The stream containing the JSP to process
0290: * @param serv javax.servlet.Servlet The servlet that is running this method.
0291: * @param req javax.servlet.ServletRequest The request for the servlet running this method.
0292: * @param res javax.servlet.ServletResponse The response for the servlet running this method.
0293: * @param convType int valid values are: CONV_HTML: convert the page to standard HTML<BR> or CONV_DREAMWEAVER: convert the page to DreamWeaver HTML (custom tags are wrapped in <MMBeginLock> <MMEndLock> tags).
0294: */
0295: public static void getInstanceVariables(InputStream in,
0296: Servlet serv, ServletRequest req, ServletResponse res,
0297: int convType, String docBase) throws java.lang.Exception {
0298: HttpServletResponseDummy dummy = new HttpServletResponseDummy(
0299: (HttpServletResponse) res, null);
0300: JspConverter con = new JspConverter(in, serv, req, dummy,
0301: convType, docBase);
0302:
0303: JspController cont = con.processDocument();
0304: if (cont != null)
0305: cont.printVars(new PrintWriter(res.getWriter()));
0306: }
0307:
0308: private TagSupport getParentTag() throws Exception {
0309: TagSupport parent = null;
0310: if (_st.size() > 0)
0311: parent = ((JspElement) _st.peek()).getHandler();
0312: return parent;
0313: }
0314:
0315: private int getTagConvertType(TagSupport handler) {
0316: if (_convType == CONV_DREAMWEAVER) {
0317: if (handler instanceof BaseBodyTag)
0318: return ((BaseBodyTag) handler).getTagConvertType();
0319: else if (handler instanceof PageTag) {
0320: if (_pageTagAdded)
0321: return BaseBodyTag.CONV_NONE;
0322: else
0323: return BaseBodyTag.CONV_PAGE_INVISIBLE;
0324: }
0325: }
0326: return BaseBodyTag.CONV_NONE;
0327: }
0328:
0329: private Hashtable getTags(String prefix) throws Exception {
0330: for (int i = 0; i < _tagLibs.size(); i++) {
0331: TwoObjectContainer cont = (TwoObjectContainer) _tagLibs
0332: .elementAt(i);
0333: String tldPrefix = (String) cont.getObject1();
0334: if (tldPrefix.equals(prefix)) {
0335: return (Hashtable) cont.getObject2();
0336: }
0337: }
0338:
0339: return null;
0340: }
0341:
0342: /**
0343: * This method will remove illegal characters for strings so they can be placed in a url link.
0344: */
0345: private String htmlEncode(String s) {
0346: if (s == null)
0347: return null;
0348:
0349: StringBuffer b = new StringBuffer();
0350: for (int i = 0; i < s.length(); i++) {
0351: char c = s.charAt(i);
0352: if (c == '"')
0353: b.append(""");
0354: else if (c == '<')
0355: b.append("<");
0356: else if (c == '>')
0357: b.append(">");
0358: else
0359: b.append(c);
0360: }
0361:
0362: return b.toString();
0363:
0364: }
0365:
0366: private TagSupport initTag(String tagName, String className,
0367: Vector attributes, TagAttributeInfo[] info)
0368: throws Exception {
0369: //check for required attributes and make sure the names are unique
0370: boolean nameChecked = false;
0371: for (int i = 0; i < info.length; i++) {
0372: if (info[i].isRequired()) {
0373: boolean reqOK = false;
0374: for (int j = 0; j < attributes.size(); j++) {
0375: ThreeObjectContainer cont = (ThreeObjectContainer) attributes
0376: .elementAt(j);
0377: String att = (String) cont.getObject1();
0378: String val = (String) cont.getObject2();
0379: if (!nameChecked && att.equals("name")) {
0380: if (_tagNames.get(val) != null)
0381: throw new Exception(
0382: "The name attribute (\""
0383: + val
0384: + "\") for the tag \""
0385: + tagName
0386: + "\" must be unique in the page. ");
0387: _tagNames.put(val, val);
0388: nameChecked = true;
0389: }
0390: if (att.equals(info[i].getName())) {
0391: if (val != null) {
0392: reqOK = true;
0393: break;
0394: }
0395: }
0396: }
0397: if (!reqOK)
0398: throw new Exception("The attribute \""
0399: + info[i].getName() + "\" for the tag \""
0400: + tagName + "\" cannot be null. ");
0401: }
0402: }
0403:
0404: Class c = Class.forName(className);
0405: TagSupport handler = (TagSupport) c.newInstance();
0406: String parm[] = new String[1];
0407:
0408: for (int i = 0; i < attributes.size(); i++) {
0409: ThreeObjectContainer cont = (ThreeObjectContainer) attributes
0410: .elementAt(i);
0411: String att = (String) cont.getObject1();
0412: String val = (String) cont.getObject2();
0413: String setMethod = (String) cont.getObject3();
0414:
0415: boolean attOK = false;
0416: for (int j = 0; j < info.length; j++) {
0417: if (att.equals(info[j].getName())) {
0418: attOK = true;
0419: break;
0420: }
0421: }
0422:
0423: if (!attOK)
0424: throw new Exception("The attribute \"" + att
0425: + "\" for the tag \"" + tagName
0426: + "\" is not valid.");
0427:
0428: if (_convType == CONV_DREAMWEAVER && att.equals("visible"))
0429: val = "true";
0430:
0431: Method m = c.getMethod(setMethod, STRING_PARM);
0432: parm[0] = val;
0433: m.invoke(handler, parm);
0434: }
0435:
0436: return handler;
0437: }
0438:
0439: private void handleInclude(int lineNo, String tagName)
0440: throws IOException {
0441: String testAtt = "page";
0442: try {
0443: if (tagName.equals("jsp:include"))
0444: parseTag(true, lineNo);
0445: else {
0446: testAtt = "file";
0447: parseTag(false, lineNo);
0448: }
0449: } catch (Exception e) {
0450: }
0451:
0452: String file = null;
0453: for (int i = 0; i < _tagAttributes.size(); i++) {
0454: ThreeObjectContainer c = (ThreeObjectContainer) _tagAttributes
0455: .elementAt(i);
0456: String att = (String) c.getObject1();
0457: String value = (String) c.getObject2();
0458: if (att.equalsIgnoreCase(testAtt))
0459: file = _documentBase + File.separatorChar + value;
0460: }
0461:
0462: FileInputStream in = new FileInputStream(file);
0463: ByteArrayOutputStream out = new ByteArrayOutputStream();
0464: int chunkSize = 2048;
0465: byte[] b = new byte[chunkSize];
0466: while (true) {
0467: if (in.available() < chunkSize) {
0468: b = new byte[in.available()];
0469: in.read(b);
0470: out.write(b);
0471: break;
0472: } else {
0473: in.read(b);
0474: out.write(b);
0475: }
0476: }
0477: in.close();
0478: byte[] content = out.toByteArray();
0479: String contentString = "";
0480: try {
0481: contentString = new String(content, "UTF-8");
0482: } catch (UnsupportedEncodingException e1) {
0483: contentString = _page = new String(content);
0484: }
0485: String leftSide = _page.substring(0, _inPos);
0486: String rightSide = _page.substring(_inPos);
0487: _page = leftSide + contentString + rightSide;
0488: _inSize += contentString.length();
0489: }
0490:
0491: private void insertTagLibrary(int lineNo) throws Exception {
0492: String prefix = "";
0493: String uri = "";
0494:
0495: try {
0496: parseTag(false, lineNo);
0497: } catch (Exception e) {
0498: }
0499:
0500: for (int i = 0; i < _tagAttributes.size(); i++) {
0501: ThreeObjectContainer c = (ThreeObjectContainer) _tagAttributes
0502: .elementAt(i);
0503: String att = (String) c.getObject1();
0504: if (att.equals("prefix"))
0505: prefix = (String) c.getObject2();
0506: else if (att.equals("uri"))
0507: uri = (String) c.getObject2();
0508: }
0509: if (uri == null || prefix == null)
0510: throw (new Exception("Incomplete taglib tag. (Line:"
0511: + lineNo + ")"));
0512:
0513: for (int i = 0; i < _tagLibs.size(); i++) {
0514: TwoObjectContainer cont = (TwoObjectContainer) _tagLibs
0515: .elementAt(i);
0516: String tldPrefix = (String) cont.getObject1();
0517: if (tldPrefix.equals(prefix))
0518: return;
0519: }
0520:
0521: TwoObjectContainer cont = new TwoObjectContainer(prefix,
0522: TagLibraryParser.getTags(uri, _app, _servlet
0523: .getServletConfig().getServletContext()));
0524: _tagLibs.add(cont);
0525:
0526: }
0527:
0528: private int nextToken() {
0529: boolean started = false;
0530: boolean quoteMode = false;
0531: boolean scriptMode = false;
0532: _nextToken.setLength(0);
0533: int length = _nextTag.length();
0534: char c = ' ';
0535: while (_nextTokenIndex < length) {
0536: c = _nextTag.charAt(_nextTokenIndex);
0537: if (c == '<' || c == '>' || c == '"' || c == '='
0538: || c == '/') {
0539: if (started & !quoteMode)
0540: return TYPE_UNQUOTED;
0541:
0542: if (c == '<') {
0543: if (_nextTag.length() > (_nextTokenIndex + 2)) {
0544: if (_nextTag.charAt(_nextTokenIndex + 1) == '%'
0545: && _nextTag.charAt(_nextTokenIndex + 2) == '=') {
0546: scriptMode = true;
0547: }
0548: }
0549: }
0550:
0551: if (c == '"' && !scriptMode) {
0552: _nextTokenIndex++;
0553: if (quoteMode)
0554: return TYPE_QUOTED;
0555: else {
0556: started = true;
0557: quoteMode = true;
0558: continue;
0559: }
0560: }
0561:
0562: if (!quoteMode && !scriptMode) {
0563: _nextTokenIndex++;
0564: if (c == '<') {
0565: _nextToken.append(c);
0566: return TYPE_START_TAG;
0567: }
0568: if (c == '/') {
0569: _nextToken.append(c);
0570: return TYPE_SLASH;
0571: } else if (c == '>') {
0572: _nextToken.append('>');
0573: return TYPE_END_TAG;
0574: } else if (c == '=') {
0575: _nextToken.append(c);
0576: return TYPE_EQUALS;
0577: }
0578: }
0579:
0580: if (c == '>' && scriptMode) {
0581: if (_nextTag.charAt(_nextTokenIndex - 1) == '%')
0582: scriptMode = false;
0583: }
0584:
0585: } else if (c == ' ' || ((int) c) == 10 || ((int) c) == 13
0586: || ((int) c) == 9) {
0587: if (started && !quoteMode)
0588: return TYPE_UNQUOTED;
0589: } else if (!started) {
0590: started = true;
0591: }
0592:
0593: if (started)
0594: _nextToken.append(c);
0595:
0596: _nextTokenIndex++;
0597: }
0598:
0599: return TYPE_ERROR;
0600: }
0601:
0602: private JspController outputDocument() throws Exception {
0603:
0604: _res.setContentType("text/html; charset=UTF-8");
0605: _st.setSize(0);
0606: boolean appendSource = false;
0607: StringBuffer source = new StringBuffer();
0608:
0609: if (_pageTag == null) {
0610: PageTag pt = new PageTag();
0611: pt.setApplication(_app);
0612: _pageTag = new JspElement("page", "", "",
0613: JspElement.TAG_EMPTY, pt, null);
0614: _doc.insert(_pageTag);
0615: JspElement end = new JspElement("endpage", "", "",
0616: JspElement.TAG_EMPTY, new EndPageTag(), null);
0617: _doc.append(end);
0618: _pageTagAdded = true;
0619: } else
0620: _pageTagAdded = false;
0621:
0622: PageContextImpl context = new PageContextImpl();
0623: context
0624: .initialize(_servlet, _req, _res, null, true, 8192,
0625: true);
0626: JspWriter top = context.getOut();
0627: JspWriter out = context.pushBody();
0628:
0629: PageTag pt = ((PageTag) _pageTag.getHandler());
0630: if (pt.getApplication() == null
0631: || pt.getApplication().equals("none"))
0632: pt.setApplication(_app);
0633: pt.setAlwaysCreateNewController(true);
0634: pt.setPageContext(context);
0635: pt.setDreamWeaverMode(_convType == CONV_DREAMWEAVER);
0636: boolean isInit = false;
0637:
0638: JspElement ele = _doc.getFirst();
0639: while (ele != null) {
0640:
0641: if (appendSource)
0642: source.append(ele.getText());
0643:
0644: int type = ele.getType();
0645: if (type == JspElement.TAG_HTML) {
0646:
0647: if (!_st.isEmpty()) {
0648: JspElement tmp = (JspElement) _st.peek();
0649: if (tmp.getHandler() instanceof BaseBodyTag) {
0650: if (((BaseBodyTag) tmp.getHandler())
0651: .hasNestedTags()) {
0652: //if a tag has nested tags, there can't be any text outside a nested tag
0653: ele = ele.getNext();
0654: continue;
0655: }
0656: }
0657: }
0658: ((BodyContentImpl) out).printNoConv(ele.getText());
0659: } else if (type == JspElement.TAG_EMPTY) {
0660: TagSupport handler = ele.getHandler();
0661: if (!appendSource) {
0662: handler.setParent(getParentTag());
0663: handler.setPageContext(context);
0664: JspWriter prevOut = out;
0665: out = context.pushBody();
0666:
0667: if (_convType == CONV_DREAMWEAVER)
0668: ((BodyContentImpl) out).setDreamWeaverConv(ele
0669: .getPrefix(), ele.getName(), ele
0670: .getText());
0671: handler.doStartTag();
0672: handler.doEndTag();
0673: if (!isInit)
0674: ((BodyContentImpl) out).writeOut(prevOut);
0675: out.clearBuffer();
0676: out = context.popBody();
0677: }
0678: if (handler instanceof PageTag) {
0679: isInit = true;
0680: ((BodyContentImpl) out).writeOut(top);
0681: } else if (handler instanceof EndPageTag && isInit) {
0682: isInit = false;
0683: ele = _pageTag;
0684: out.clearBuffer();
0685: if (_bodyTag == null) {
0686: JspWriter prevOut = out;
0687: out = context.pushBody();
0688: if (_convType == CONV_DREAMWEAVER)
0689: ((BodyContentImpl) out).setDreamWeaverConv(
0690: ele.getPrefix(), "HtmlBody", "");
0691: pt.getControllerObject().generateBodyHtml(out);
0692: ((BodyContentImpl) out).writeOut(prevOut);
0693: out.clearBuffer();
0694: out = context.popBody();
0695: }
0696: }
0697: } else if (type == JspElement.TAG_BODY_START) {
0698: BodyTagSupport handler = (BodyTagSupport) ele
0699: .getHandler();
0700: handler.setPageContext(context);
0701: handler.setParent(getParentTag());
0702:
0703: int ret = handler.doStartTag();
0704: if (ret != Tag.SKIP_BODY) {
0705: int convType = getTagConvertType(handler);
0706: if (convType == BaseBodyTag.CONV_PAGE_INVISIBLE)
0707: out.print(TagWriter.dreamWeaverConv(ele
0708: .getPrefix(), ele.getName(), ele
0709: .getText(), ""));
0710: else if (convType != BaseBodyTag.CONV_NONE) {
0711: BaseTagHelper helper = ((BaseBodyTag) handler)
0712: .getHelper();
0713: if (convType == BaseBodyTag.CONV_WRAP_ALL_NESTED
0714: && !isInit) {
0715: appendSource = true;
0716: source.append(ele.getText());
0717: } else if (convType == BaseBodyTag.CONV_INVISIBLE
0718: && !isInit) {
0719: ((BodyContentImpl) out).setDreamWeaverConv(
0720: ele.getPrefix(), ele.getName(), ele
0721: .getText());
0722: TagWriter w = ((BaseBodyTag) handler)
0723: .getTagWriter();
0724: w.setWriter(out);
0725: w.print("", TagWriter.TYPE_BEGIN_TAG);
0726: ((BodyContentImpl) out)
0727: .clearDreamWeaverConv();
0728: } else if (helper.getComponent() instanceof JspDataTable
0729: && isInit) {
0730: DataStoreBuffer dsb = new DataStoreBuffer();
0731: dsb.insertRow();
0732: ((JspDataTable) helper.getComponent())
0733: .setDataStoreBuffer(dsb);
0734: }
0735: }
0736:
0737: _st.push(ele);
0738: out = context.pushBody();
0739:
0740: if (convType == BaseBodyTag.CONV_WRAP_ALL_NESTED) {
0741: String name = ele.getName();
0742: //Special case for input tag, make the tag name the type attribute instead of the tag name
0743: //for easier parsing later.
0744: if (ele.getHandler() instanceof InputTag) {
0745: name = ((InputTag) ele.getHandler())
0746: .getType();
0747: if (name.equals("text"))
0748: name = "textedit";
0749: else if (name.equals("image"))
0750: name = "submitimage";
0751: }
0752:
0753: ((BodyContentImpl) out).setDreamWeaverConv(ele
0754: .getPrefix(), name, ele.getText());
0755: }
0756:
0757: handler.setBodyContent((BodyContent) out);
0758: handler.doInitBody();
0759: } else {
0760: handler.doEndTag();
0761: ele = ele.getClosingTag();
0762: }
0763: } else if (type == JspElement.TAG_BODY_END) {
0764: JspElement cur = (JspElement) _st.peek();
0765: BodyTagSupport handler = (BodyTagSupport) cur
0766: .getHandler();
0767: int convType = getTagConvertType(handler);
0768: if (convType == BaseBodyTag.CONV_PAGE_INVISIBLE) {
0769: if (!isInit)
0770: out.print(TagWriter.dreamWeaverConv("/"
0771: + ele.getPrefix(), ele.getName(), ele
0772: .getText(), ""));
0773: } else if (convType == BaseBodyTag.CONV_WRAP_ALL_NESTED) {
0774: if (context.getOut() instanceof BodyContentImpl) {
0775: ((BodyContentImpl) context.getOut())
0776: .setOrigTag(source.toString());
0777: source.setLength(0);
0778: appendSource = false;
0779: }
0780: }
0781: int ret = handler.doAfterBody();
0782: if (ret == BodyTag.EVAL_BODY_TAG)
0783: ele = cur;
0784: else {
0785: _st.pop();
0786: out = context.popBody();
0787: if (convType == BaseBodyTag.CONV_INVISIBLE) {
0788: if (!isInit)
0789: out.print(TagWriter.dreamWeaverConv("/"
0790: + ele.getPrefix(), ele.getName(),
0791: ele.getText(), ""));
0792: }
0793:
0794: ret = handler.doEndTag();
0795: if (ret == BodyTagSupport.SKIP_PAGE) {
0796: if (pt == null)
0797: return null;
0798: else
0799: return pt.getControllerObject();
0800: }
0801: }
0802: }
0803:
0804: ele = ele.getNext();
0805: }
0806:
0807: ((BodyContent) out).writeOut(top);
0808: out.clearBuffer();
0809: top.flush();
0810: top.close();
0811: context.popBody();
0812:
0813: if (pt == null)
0814: return null;
0815: else
0816: return pt.getControllerObject();
0817: }
0818:
0819: private void outputErrors() throws Exception {
0820: PrintWriter out = _res.getWriter();
0821: int type = 0;
0822:
0823: boolean headingPrinted = false;
0824: String heading = "<FONT SIZE=\"5\" COLOR=\"RED\">"
0825: + _errorCount + " Error"
0826: + (_errorCount == 1 ? " " : "s ")
0827: + "Found in Document. </FONT><BR>";
0828: if (_bodyTag == null) {
0829: if (_convType == CONV_DREAMWEAVER)
0830: out.println(TagWriter.dreamWeaverConv("", "", "",
0831: heading));
0832: else
0833: out.println(heading);
0834: headingPrinted = true;
0835: }
0836:
0837: JspElement e = _doc.getFirst();
0838: while (e != null) {
0839: type = e.getType();
0840: if (type == JspElement.TAG_ERROR) {
0841: String output = htmlEncode(e.getError()) + "<BR>";
0842: if (_convType == CONV_DREAMWEAVER)
0843: output = TagWriter.dreamWeaverConv(e.getPrefix(), e
0844: .getName(), e.getText(), htmlEncode(e
0845: .getError())
0846: + "<BR>");
0847: out.println(output);
0848: MessageLog.writeInfoMessage("Error in JSP Translation:"
0849: + e.getError(), this );
0850: } else if (type == JspElement.TAG_EMPTY
0851: && e.getName().equals("body")) {
0852: out.print(e.getText());
0853: if (!headingPrinted) {
0854: if (_convType == CONV_DREAMWEAVER)
0855: out.println(TagWriter.dreamWeaverConv("", "",
0856: "", heading));
0857: else
0858: out.println(heading);
0859: headingPrinted = true;
0860: }
0861: } else
0862: out.print(e.getText());
0863:
0864: e = e.getNext();
0865: }
0866: out.flush();
0867:
0868: }
0869:
0870: private void parseDocument() throws IOException {
0871: _doc = new JspDocument();
0872: _errorCount = 0;
0873: int lineCount = 1;
0874: char i = readInput();
0875:
0876: //parse the document
0877: while (i != 0) {
0878: char c = (char) i;
0879: if (c == '\n')
0880: lineCount++;
0881:
0882: if (c == '\"') {
0883: if (_quote == c)
0884: _quote = ' ';
0885: else
0886: _quote = c;
0887: if (_mode == MODE_TEXT || _mode == MODE_SCRIPT
0888: || _mode == MODE_COMMENT)
0889: _nextText.append(c);
0890: else
0891: _nextTag.append(c);
0892: } else if (c == '<') {
0893: if (_quote == ' ' && _mode != MODE_SCRIPT
0894: && _mode != MODE_COMMENT) {
0895: if (_mode == MODE_TEXT) {
0896: if (_nextText.length() > 0)
0897: processText(_nextText.toString());
0898: }
0899: _mode = MODE_TAG;
0900: _nextTag.setLength(0);
0901: _nextText.setLength(0);
0902: _nextTagName.setLength(0);
0903: _nextTagPrefix.setLength(0);
0904: _tagNameStarted = false;
0905: _tagNameEnded = false;
0906: _tagPrefixEnded = false;
0907: _tagNamePos = 0;
0908: _nextTag.append(c);
0909: } else {
0910: if (_mode == MODE_TEXT || _mode == MODE_SCRIPT
0911: || _mode == MODE_COMMENT)
0912: _nextText.append(c);
0913: else
0914: _nextTag.append(c);
0915: }
0916: } else if (c == '>') {
0917: if (_mode == MODE_COMMENT) {
0918: if (_nextText.toString().endsWith("--")) {
0919: _nextText.append(">");
0920: processText(_nextText.toString());
0921: _nextText.setLength(0);
0922: _nextTag.setLength(0);
0923: _mode = MODE_TEXT;
0924: } else
0925: _nextText.append(">");
0926: } else if (_mode == MODE_SCRIPT) {
0927: if (_nextText.toString().toLowerCase().trim()
0928: .endsWith("/script")) {
0929: _nextText.append(">");
0930: processText(_nextText.toString());
0931: _nextText.setLength(0);
0932: _mode = MODE_TEXT;
0933: } else
0934: _nextText.append(">");
0935: } else if (_quote == ' ') {
0936: _mode = MODE_TEXT;
0937: _nextTag.append(c);
0938: try {
0939: String nextTagName = _nextTagName.toString();
0940: if (nextTagName.equals("MM:BeginLock")) {
0941: _nextTokenIndex = _tagNamePos + 1;
0942: int type = nextToken();
0943: if (type == TYPE_UNQUOTED
0944: && _nextToken.toString()
0945: .toLowerCase().equals(
0946: "translatorclass")) {
0947: try {
0948: parseTag(true, lineCount);
0949: } catch (Exception e) {
0950: }
0951: OUTER: for (int j = 0; j < _tagAttributes
0952: .size(); j++) {
0953: ThreeObjectContainer oc = (ThreeObjectContainer) _tagAttributes
0954: .elementAt(j);
0955: String att = (String) oc
0956: .getObject1();
0957: if (att.equals("translatorClass")) {
0958: String classType = (String) oc
0959: .getObject2();
0960: if (classType
0961: .equals("MM_JSPSCRIPT"))
0962: for (int k = 0; k < _tagAttributes
0963: .size(); k++) {
0964: ThreeObjectContainer oc2 = (ThreeObjectContainer) _tagAttributes
0965: .elementAt(k);
0966: String att2 = (String) oc2
0967: .getObject1();
0968: if (att2.equals("orig")) {
0969: String origString = java.net.URLDecoder
0970: .decode((String) oc2
0971: .getObject2());
0972: if (origString
0973: .indexOf("taglib") != -1) {
0974:
0975: int tokenIndex = origString
0976: .indexOf("taglib") + 6;
0977: //Set nexttag and nextTokenIndex settings so nextToken() will parse the lockedOrigTag correctly
0978: StringBuffer origNextTag = _nextTag;
0979: _nextTag = new StringBuffer(
0980: origString);
0981: //
0982: int origTokenIndex = _nextTokenIndex;
0983: _nextTokenIndex = tokenIndex;
0984: //
0985: insertTagLibrary(lineCount);
0986: //Set nextTag and nextTokenIndex back to its original values
0987: _nextTokenIndex = origTokenIndex;
0988: _nextTag = origNextTag;
0989: break OUTER;
0990: }
0991: }
0992: }
0993: }
0994: }
0995:
0996: }
0997:
0998: }
0999: if (_handleIncludes) {
1000: if (nextTagName.equals("jsp:include"))
1001: handleInclude(lineCount, nextTagName);
1002: }
1003:
1004: if (nextTagName.equals("script")) {
1005: processText(_nextTag.toString());
1006: _mode = MODE_SCRIPT;
1007: } else if (nextTagName.equals("%@")) {
1008: _nextTokenIndex = _tagNamePos + 1;
1009: int type = nextToken();
1010: String nextTokenSt = _nextToken.toString()
1011: .toLowerCase();
1012: if (type == TYPE_UNQUOTED
1013: && nextTokenSt.equals("include"))
1014: handleInclude(lineCount, _nextTag
1015: .toString());
1016: else if (type == TYPE_UNQUOTED
1017: && _nextToken.toString()
1018: .toLowerCase().equals(
1019: "taglib"))
1020: insertTagLibrary(lineCount);
1021:
1022: if (_convType != CONV_HTML)
1023: processText(_nextTag.toString());
1024: } else {
1025: String prefix = _nextTagPrefix.toString();
1026: Hashtable info = getTags(prefix);
1027: if (info == null) {
1028: processText(_nextTag.toString());
1029: if (nextTagName.equals("body"))
1030: _bodyTag = _doc.getLast();
1031: } else {
1032: int type = parseTag(true, lineCount);
1033: if (type == JspElement.TAG_BODY_START
1034: || type == JspElement.TAG_EMPTY)
1035: nextTagName = nextTagName
1036: .substring(prefix.length() + 1);
1037: else if (type == JspElement.TAG_BODY_END)
1038: nextTagName = nextTagName
1039: .substring(prefix.length() + 2);
1040: processTag(nextTagName, prefix,
1041: _nextTag.toString(),
1042: _tagAttributes, type, info,
1043: lineCount);
1044: }
1045: }
1046: _nextTag.setLength(0);
1047: } catch (Exception e) {
1048: processTagSyntaxError(_nextTagName.toString(),
1049: _nextTagPrefix.toString(), _nextTag
1050: .toString(), e.getMessage());
1051: }
1052: } else {
1053: if (_mode == MODE_TEXT || _mode == MODE_SCRIPT
1054: || _mode == MODE_COMMENT)
1055: _nextText.append(c);
1056: else
1057: _nextTag.append(c);
1058: }
1059: } else if (_mode == MODE_TEXT || _mode == MODE_SCRIPT
1060: || _mode == MODE_COMMENT) {
1061: _nextText.append(c);
1062: } else {
1063: if (c == '-' && !_tagNameEnded) {
1064: if (_nextTag.toString().equals("<!-")) {
1065: _nextText.setLength(0);
1066: _nextText.append("<!--");
1067: _nextTag.setLength(0);
1068: _mode = MODE_COMMENT;
1069: }
1070: }
1071:
1072: if (c == ' ' || ((int) c) == 10 || ((int) c) == 13
1073: || ((int) c) == 9) {
1074: if (_tagNameStarted)
1075: _tagNameEnded = true;
1076: } else
1077: _tagNameStarted = true;
1078:
1079: if (c == ':')
1080: _tagPrefixEnded = true;
1081:
1082: if (!_tagNameEnded) {
1083: _tagNamePos++;
1084: if (_tagNameStarted) {
1085: _nextTagName.append(c);
1086: if (!_tagPrefixEnded && c != '/')
1087: _nextTagPrefix.append(Character
1088: .toLowerCase(c));
1089: }
1090: }
1091: _nextTag.append(c);
1092: }
1093:
1094: i = readInput();
1095: }
1096:
1097: if (_nextTag.length() > 0)
1098: processText(_nextTag.toString());
1099:
1100: //check errors
1101: StringBuffer error = new StringBuffer();
1102: if (!_st.isEmpty()) {
1103: error
1104: .append("Error in document. Failed to find closing tags for:");
1105: while (!_st.isEmpty()) {
1106: error.append(" -");
1107: error.append(((JspElement) _st.pop()).getName());
1108: }
1109: _errorCount++;
1110: error.append('\n');
1111: }
1112: if (_pageTag != null && _endPageTag == null) {
1113: error
1114: .append("Error in document. Could not find \"endpage\" tag.");
1115: _errorCount++;
1116: } else if (_endPageTag != null && _pageTag == null) {
1117: error
1118: .append("Error in document. Could not find \"page\" tag.");
1119: _errorCount++;
1120: }
1121:
1122: if (error.length() > 0)
1123: _doc.getLast().setError(error.toString());
1124:
1125: if (_debugOut != null)
1126: _debugOut.close();
1127: }
1128:
1129: private int parseTag(boolean resetCounter, int lineNo)
1130: throws Exception {
1131: if (resetCounter)
1132: _nextTokenIndex = _tagNamePos + 1;
1133:
1134: _tagAttributes.setSize(0);
1135:
1136: if (_nextTagName.charAt(_nextTagName.length() - 1) == '/')
1137: return JspElement.TAG_EMPTY;
1138:
1139: if (_nextTagName.charAt(0) == '/')
1140: return JspElement.TAG_BODY_END;
1141:
1142: int tokType = nextToken();
1143: ThreeObjectContainer nextAtt = new ThreeObjectContainer();
1144: while (tokType != TYPE_SLASH && tokType != TYPE_END_TAG) {
1145: if (tokType == TYPE_UNQUOTED) {
1146: if (nextAtt.getObject1() != null)
1147: throw (new Exception("Error in <" + _nextTagName
1148: + ">: value for \"" + nextAtt.getObject1()
1149: + "\" must be in quotes. (Line:" + lineNo
1150: + ")"));
1151: else {
1152: nextAtt.setObject1(_nextToken.toString());
1153: _nextToken.setCharAt(0, Character
1154: .toUpperCase(_nextToken.charAt(0)));
1155: _nextToken.insert(0, "set");
1156: nextAtt.setObject3(_nextToken.toString());
1157: }
1158: } else if (tokType == TYPE_EQUALS) {
1159: if (nextAtt.getObject1() == null)
1160: throw (new Exception(
1161: "Error in <"
1162: + _nextTagName
1163: + ">: equal sign found before attribute name (Line:"
1164: + lineNo + ")"));
1165: } else if (tokType == TYPE_QUOTED) {
1166: if (nextAtt.getObject1() == null)
1167: throw (new Exception(
1168: "Error in <"
1169: + _nextTagName
1170: + ">: attribute value:\""
1171: + _nextToken
1172: + "\" does not have a corresponding attribute. (Line:"
1173: + lineNo + ")"));
1174: else {
1175: nextAtt.setObject2(_nextToken.toString());
1176: _tagAttributes.addElement(nextAtt);
1177: nextAtt = new ThreeObjectContainer();
1178: }
1179: }
1180: tokType = nextToken();
1181: }
1182:
1183: if (nextAtt.getObject1() != null
1184: && nextAtt.getObject2() == null)
1185: throw (new Exception("Error in <" + _nextTagName
1186: + ">: value for attribute \""
1187: + nextAtt.getObject1() + "\" is missing. (Line:"
1188: + lineNo + ")"));
1189:
1190: if (tokType == TYPE_SLASH)
1191: return JspElement.TAG_EMPTY;
1192: else
1193: return JspElement.TAG_BODY_START;
1194:
1195: }
1196:
1197: private JspController processDocument() {
1198: try {
1199: parseDocument();
1200: if (_errorCount > 0)
1201: outputErrors();
1202: else
1203: return outputDocument();
1204: } catch (Exception e) {
1205: e.printStackTrace(System.err);
1206: MessageLog.writeErrorMessage("processDocument", e, this );
1207: }
1208: return null;
1209: }
1210:
1211: private void processTag(String tagName, String tagPrefix,
1212: String text, Vector attributes, int type, Hashtable tags,
1213: int lineNo) {
1214: if (tagName.charAt(tagName.length() - 1) == '/')
1215: tagName = tagName.substring(0, tagName.length() - 1);
1216:
1217: TagInfo t = (TagInfo) tags.get(tagName);
1218:
1219: if (t == null) {
1220: _doc.append(new JspElement(tagName, tagPrefix, text,
1221: JspElement.TAG_ERROR, null, "Error tag \""
1222: + tagName
1223: + "\" not found in library. (Line:"
1224: + lineNo + ")"));
1225: _errorCount++;
1226: } else {
1227: if (t.getBodyContent() == TagInfo.BODY_CONTENT_JSP) {
1228: if (type == JspElement.TAG_EMPTY) {
1229: _doc.append(new JspElement(tagName, tagPrefix,
1230: text, JspElement.TAG_ERROR, null,
1231: "Error tag \"" + tagName
1232: + "\" cannot be empty. (Line: "
1233: + lineNo + ")"));
1234: _errorCount++;
1235: return;
1236: }
1237: } else if (t.getBodyContent() == TagInfo.BODY_CONTENT_EMPTY) {
1238: if (type == JspElement.TAG_BODY_START) {
1239: _doc.append(new JspElement(tagName, tagPrefix,
1240: text, JspElement.TAG_ERROR, null,
1241: "Error tag \"" + tagName
1242: + "\" must be empty. (Line: "
1243: + lineNo + ")"));
1244: _errorCount++;
1245: return;
1246: } else if (type == JspElement.TAG_BODY_END) {
1247: _doc
1248: .append(new JspElement(
1249: tagName,
1250: tagPrefix,
1251: text,
1252: JspElement.TAG_ERROR,
1253: null,
1254: "Error tag \""
1255: + tagName
1256: + "\" is an empty tag and so it cannot have a closing tag. (Line: "
1257: + lineNo + ")"));
1258: _errorCount++;
1259: return;
1260: }
1261: }
1262:
1263: try {
1264: JspElement ele = null;
1265:
1266: if (type == JspElement.TAG_EMPTY) {
1267: TagSupport handler = initTag(tagName, t
1268: .getTagClassName(), attributes, t
1269: .getAttributes());
1270:
1271: ele = new JspElement(tagName, tagPrefix, text,
1272: checkTagType(handler, type), handler, null);
1273: if (tagName.equals("page")) {
1274: if (_pageTag != null)
1275: throw new Exception(
1276: "Error. Only one page tag is allowed per page.");
1277: ((PageTag) handler).setController(null);
1278: ((PageTag) handler)
1279: .setSecondarycontroller(null);
1280: _pageTag = ele;
1281: } else if (tagName.equals("endpage")) {
1282: if (_endPageTag != null)
1283: throw new Exception(
1284: "Error. Only one endpage tag is allowed per page.");
1285: _endPageTag = ele;
1286: } else if (tagName.equals("body")) {
1287: if (_bodyTag != null)
1288: throw new Exception(
1289: "Error. Only one body tag is allowed per page.");
1290: _bodyTag = ele;
1291: } else if (tagName.equals("endbody")) {
1292: if (_endBodyTag != null)
1293: throw new Exception(
1294: "Error. Only one end body tag is allowed per page.");
1295: _endBodyTag = ele;
1296: }
1297: verifyTagParent(ele);
1298: } else if (type == JspElement.TAG_BODY_START) {
1299: TagSupport handler = initTag(tagName, t
1300: .getTagClassName(), attributes, t
1301: .getAttributes());
1302: ele = new JspElement(tagName, tagPrefix, text,
1303: checkTagType(handler, type), handler, null);
1304: verifyTagParent(ele);
1305: _st.push(ele);
1306:
1307: } else if (type == JspElement.TAG_BODY_END) {
1308: if (_st.isEmpty())
1309: throw new Exception(
1310: "End tag does not have a corresponding begin tag.");
1311: else {
1312: JspElement start = (JspElement) _st.peek();
1313: if (!start.getName().equals(tagName))
1314: throw new Exception(
1315: "Improper nesting of tags. Expecting end tag for \""
1316: + start.getName()
1317: + "\" and found end tag for \""
1318: + tagName + "\" instead.");
1319: _st.pop();
1320: TagSupport handler = start.getHandler();
1321: String startTag = start.getText();
1322: String endTag = text;
1323: ele = new JspElement(tagName, tagPrefix, text,
1324: checkTagType(handler, type), handler,
1325: null);
1326: start.setClosingTag(ele);
1327: TagWriter writer = (_convType == CONV_DREAMWEAVER ? new TagWriter(
1328: tagPrefix, tagName, startTag, endTag)
1329: : new TagWriter());
1330: if (handler instanceof BaseBodyTag)
1331: ((BaseBodyTag) handler)
1332: .setTagWriter(writer);
1333: }
1334: }
1335:
1336: _doc.append(ele);
1337:
1338: } catch (Exception ex) {
1339: _doc.append(new JspElement(tagName, tagPrefix, text,
1340: JspElement.TAG_ERROR, null,
1341: "Error processing tag \"" + tagName + "\": "
1342: + ex.toString() + "," + ex.getMessage()
1343: + " (Line:" + lineNo + ")"));
1344: _errorCount++;
1345: }
1346: }
1347: }
1348:
1349: private void processTagSyntaxError(String tagName,
1350: String tagPrefix, String text, String error) {
1351: _errorCount++;
1352: _doc.append(new JspElement(tagName, tagPrefix, text,
1353: JspElement.TAG_ERROR, null, error));
1354: }
1355:
1356: private void processText(String text) {
1357: JspElement ele = new JspElement("html", null, text,
1358: JspElement.TAG_HTML, null, null);
1359: _doc.append(ele);
1360: }
1361:
1362: private char readInput() throws IOException {
1363: if (_inPos >= _inSize)
1364: return 0;
1365: else
1366: return _page.charAt(_inPos++);
1367: }
1368:
1369: private void verifyTagParent(JspElement child) throws Exception {
1370: _nestTest.setLength(0);
1371: _nestTest.append("*-");
1372: _nestTest.append(child.getName());
1373: if (_tagMap.get(_nestTest.toString()) != null) {
1374: if (_st.isEmpty())
1375: throw new Exception("Error. The tag \""
1376: + child.getName()
1377: + "\" must be inside another tag.");
1378: else {
1379: JspElement parent = (JspElement) _st.peek();
1380: _nestTest.setLength(0);
1381: _nestTest.append(parent.getName());
1382: _nestTest.append("-");
1383: _nestTest.append(child.getName());
1384: if (!_tagMap.containsKey(_nestTest.toString()))
1385: throw new Exception("Error. The tag \""
1386: + child.getName()
1387: + "\" cannot be nested in the tag \""
1388: + parent.getName() + "\"");
1389: }
1390: }
1391:
1392: if (!_st.isEmpty()) {
1393: JspElement parent = (JspElement) _st.peek();
1394: _nestTest.setLength(0);
1395: _nestTest.append(parent.getName());
1396: _nestTest.append("-*");
1397: if (_tagMap.get(_nestTest.toString()) != null) {
1398: _nestTest.setLength(_nestTest.length() - 1);
1399: _nestTest.append(child.getName());
1400: if (!_tagMap.containsKey(_nestTest.toString()))
1401: throw new Exception("Error. The tag \""
1402: + child.getName()
1403: + "\" cannot be nested in the tag \""
1404: + parent.getName() + "\"");
1405: }
1406:
1407: }
1408:
1409: }
1410:
1411: private void setHandleIncludes(String docBase) {
1412: _handleIncludes = true;
1413: _documentBase = docBase;
1414:
1415: }
1416:
1417: }
|