⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.java

📁 非常接近C/S操作方式的Java Ajax框架-ZK 用ZK框架使你的B/S应用程序更漂亮更易操作。 官网:www.zkoss.org
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* Parser.java{{IS_NOTE	Purpose:			Description:			History:		Sat Sep 17 12:12:41     2005, Created by tomyeh}}IS_NOTECopyright (C) 2004 Potix Corporation. All Rights Reserved.{{IS_RIGHT	This program is distributed under GPL Version 2.0 in the hope that	it will be useful, but WITHOUT ANY WARRANTY.}}IS_RIGHT*/package org.zkoss.web.servlet.dsp.impl;import java.util.Map;import java.util.HashMap;import java.util.Iterator;import java.io.IOException;import java.io.FileNotFoundException;import java.net.URL;import javax.servlet.jsp.el.FunctionMapper;import org.zkoss.lang.D;import org.zkoss.lang.Classes;import org.zkoss.util.logging.Log;import org.zkoss.util.resource.Locator;import org.zkoss.el.SimpleMapper;import org.zkoss.idom.input.SAXBuilder;import org.zkoss.idom.Element;import org.zkoss.idom.util.IDOMs;import org.zkoss.web.mesg.MWeb;import org.zkoss.web.servlet.ServletException;import org.zkoss.web.servlet.dsp.*;import org.zkoss.web.servlet.dsp.action.Page;import org.zkoss.web.servlet.dsp.action.Action;/** * Used to parse a DSP page into a meta format called * {@link Interpretation}. * * @author tomyeh */public class Parser {	private static final Log log = Log.lookup(Parser.class);	/** Parses the content into a meta format	 *	 * @param content the content to parse; never null.	 * @param ctype the content type. Optional. It is used only if	 * no page action at all. If it is not specified and not page	 * action, "text/html" is assumed.	 * @param fm a pre-defined function mapper, or null to ignore.	 * @param loc used to locate the resource such as taglib.	 * It could null only if DSP contains no such resource.	 */	public Interpretation parse(String content, String ctype,	FunctionMapper fm, Locator loc)	throws javax.servlet.ServletException, IOException {		final Context ctx = new Context(content, fm, loc);		final RootNode root = new RootNode(ctx.mapper);		parse0(ctx, root, 0, content.length());		if (!ctx.pageDefined) {			//We always create a page definition			if (D.ON && log.debugable()) log.debug("Use default content type: "+ctype);			final ActionNode action = new ActionNode(Page.class, 0);			root.addChild(0, action);			final Map attrs = new HashMap(2);			attrs.put("contentType", ctype != null ? ctype: "text/html");			applyAttrs("page", action, attrs);		}		return root;	}	/** Recursively parse the content into a tree of {@link Node}.	 */	private static void parse0(Context ctx, Node parent, int from, int to)	throws javax.servlet.ServletException, IOException {		boolean esc = false;		final StringBuffer sb = new StringBuffer(512);		for (int j = from; j < to; ++j) {			char cc = ctx.content.charAt(j);			//We only recognize <%, <\%, ${, $\{ and <xx:yy>			switch (cc) {			case '<':				if (j + 1 < to) {					char c2 = ctx.content.charAt(j + 1);					if (c2 == '\\') {						if (j + 2 < to && ctx.content.charAt(j + 2) == '%')							++j; //skip '\\'					} else if (c2 == '%') {						addText(parent, sb);						j = parseControl(ctx, parent, j, to);						continue;					} else {						final int oldLines = ctx.nLines;						int k = skipWhitespaces(ctx, j + 1, to);						int l = nextSeparator(ctx, k, to);						if (l >= to || l == k						|| ctx.content.charAt(l) != ':') {							ctx.nLines = oldLines;							break; //bypass what we don't recognize						}						final String prefix = ctx.content.substring(k, l);						if (!ctx.hasPrefix(prefix)) {							ctx.nLines = oldLines;							break; //bypass what we don't recognize						}						addText(parent, sb);						j = parseAction(ctx, parent, prefix, l, to);						continue;					}				}				break;			case '$':				if (j + 1 < to) {					char c2 = ctx.content.charAt(j + 1);					if (c2 == '\\') {						if (j + 2 < to && ctx.content.charAt(j + 2) == '{')							++j; //skip '\\'					} else if (c2 == '{') {						addText(parent, sb);						j = parseEL(ctx, parent, j, to);						continue;					}				}				break;			case '\n':				++ctx.nLines;			}			sb.append(cc);		}		addText(parent, sb);	}	/** Parses a control (e.g., &lt;% page %&gt;) starting at from,	 * and returns the postion of '&gt' (in %&gt;).	 */	private static int parseControl(Context ctx, Node parent,	int from, int to)	throws javax.servlet.ServletException, IOException {		int j = from + 2;		if (j + 1 >= to)			throw new ServletException(MWeb.DSP_ACTION_NOT_TERMINATED,				new Object[] {null, new Integer(ctx.nLines)});		//0. comment		char cc = ctx.content.charAt(j);		if (cc == '-' && ctx.content.charAt(j + 1)  == '-') { //comment			for (int end = to - 4;; ++j) {				if (j > end)					throw new ServletException(MWeb.DSP_COMMENT_NOT_TERMINATED,						new Integer(ctx.nLines));				if (ctx.content.charAt(j) == '\n')					++ctx.nLines;				else if (startsWith(ctx.content, j, to, "--%>"))					return j + 3;			}		}		if (cc != '@')			throw new ServletException(MWeb.DSP_EXPECT_CHARACTER,				new Object[] {new Character('@'), new Integer(ctx.nLines)});		//1: which control		j = skipWhitespaces(ctx, j + 1, to);		int k = nextSeparator(ctx, j, to);		if (k >= to)			throw new ServletException(MWeb.DSP_ACTION_NOT_TERMINATED,				new Object[] {null, new Integer(ctx.nLines)});		final ActionNode action;		final String ctlnm = ctx.content.substring(j, k);		if ("taglib".equals(ctlnm)) {			action = null;		} else if ("page".equals(ctlnm)) {			ctx.pageDefined = true;			parent.addChild(action = new ActionNode(Page.class, ctx.nLines));		} else {			throw new ServletException(MWeb.DSP_UNKNOWN_ACTION,				new Object[] {ctlnm, new Integer(ctx.nLines)});		}		//2: parse attributes		final Map attrs = new HashMap();		k = parseAttrs(ctx, attrs, ctlnm, k, to);		cc = ctx.content.charAt(k);		if (cc != '%')			throw new ServletException(MWeb.DSP_EXPECT_CHARACTER,				new Object[] {new Character('%'), new Integer(ctx.nLines)});		if (action == null) { //taglib			final String uri = (String)attrs.get("uri"),				prefix = (String)attrs.get("prefix");			if (prefix == null || uri == null)				throw new ServletException(MWeb.DSP_TAGLIB_ATTRIBUTE_REQUIRED, new Integer(ctx.nLines));			ctx.loadTaglib(prefix, uri);		} else {			applyAttrs(ctlnm, action, attrs);		}		if (++k >= to || ctx.content.charAt(k) != '>')			throw new ServletException(MWeb.DSP_ACTION_NOT_TERMINATED,				new Object[] {ctlnm, new Integer(ctx.nLines)});		return k;	}	/** Parses an action (e.g., &lt;c:forEach...&gt;...&lt;/c:forEach&gt;).	 * @param from the position of ':'	 * @return the postion of the last '&gt'.	 */	private static int parseAction(Context ctx, Node parent,	String prefix, int from, int to)	throws javax.servlet.ServletException, IOException {		//1: which action		int j = skipWhitespaces(ctx, from + 1, to);		int k = nextSeparator(ctx, j, to);		if (k >= to)			throw new ServletException(MWeb.DSP_ACTION_NOT_TERMINATED,				new Object[] {prefix+':', new Integer(ctx.nLines)});		if (k == j)			throw new ServletException(MWeb.DSP_ACTION_REQUIRED, new Integer(ctx.nLines));		final String actnm = ctx.content.substring(j, k);		final Class actcls = ctx.getActionClass(prefix, actnm);		if (actcls == null)			throw new ServletException(MWeb.DSP_UNKNOWN_ACTION,				new Object[] {prefix+':'+actnm, new Integer(ctx.nLines)});		final ActionNode action = new ActionNode(actcls, ctx.nLines);		parent.addChild(action);		if (D.ON && log.debugable()) log.debug("Action "+actnm);		//2: action's attributes		final Map attrs = new HashMap();		j = parseAttrs(ctx, attrs, actnm, k, to);		char cc = ctx.content.charAt(j);		boolean ended = cc == '/';		if (!ended && cc != '>')			throw new ServletException(MWeb.DSP_UNEXPECT_CHARACTER,				new Object[] {new Character(cc), new Integer(ctx.nLines)});		applyAttrs(actnm, action, attrs);		if (ended) {			if (j + 1 >= to || ctx.content.charAt(j + 1) != '>')				throw new ServletException(MWeb.DSP_ACTION_NOT_TERMINATED,					new Object[] {prefix+':'+actnm, new Integer(action.getLineNumber())});			return j + 1;		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -