| /* |
| * Copyright 1999,2004 The Apache Software Foundation. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.jasper.compiler; |
| |
| import java.util.*; |
| import java.io.*; |
| import javax.servlet.ServletContext; |
| |
| import org.apache.jasper.JasperException; |
| import org.apache.jasper.xmlparser.ParserUtils; |
| import org.apache.jasper.xmlparser.TreeNode; |
| import org.apache.jasper.compiler.tagplugin.TagPlugin; |
| import org.apache.jasper.compiler.tagplugin.TagPluginContext; |
| |
| /** |
| * Manages tag plugin optimizations. |
| * @author Kin-man Chung |
| */ |
| |
| public class TagPluginManager { |
| |
| private static final String TAG_PLUGINS_XML = "/WEB-INF/tagPlugins.xml"; |
| private static final String TAG_PLUGINS_ROOT_ELEM = "tag-plugins"; |
| |
| private boolean initialized = false; |
| private HashMap tagPlugins = null; |
| private ServletContext ctxt; |
| private PageInfo pageInfo; |
| |
| public TagPluginManager(ServletContext ctxt) { |
| this.ctxt = ctxt; |
| } |
| |
| public void apply(Node.Nodes page, ErrorDispatcher err, PageInfo pageInfo) |
| throws JasperException { |
| |
| init(err); |
| if (tagPlugins == null || tagPlugins.size() == 0) { |
| return; |
| } |
| |
| this.pageInfo = pageInfo; |
| |
| page.visit(new Node.Visitor() { |
| public void visit(Node.CustomTag n) |
| throws JasperException { |
| invokePlugin(n); |
| visitBody(n); |
| } |
| }); |
| |
| } |
| |
| private void init(ErrorDispatcher err) throws JasperException { |
| if (initialized) |
| return; |
| |
| InputStream is = ctxt.getResourceAsStream(TAG_PLUGINS_XML); |
| if (is == null) |
| return; |
| |
| TreeNode root = (new ParserUtils()).parseXMLDocument(TAG_PLUGINS_XML, |
| is); |
| if (root == null) { |
| return; |
| } |
| |
| if (!TAG_PLUGINS_ROOT_ELEM.equals(root.getName())) { |
| err.jspError("jsp.error.plugin.wrongRootElement", TAG_PLUGINS_XML, |
| TAG_PLUGINS_ROOT_ELEM); |
| } |
| |
| tagPlugins = new HashMap(); |
| Iterator pluginList = root.findChildren("tag-plugin"); |
| while (pluginList.hasNext()) { |
| TreeNode pluginNode = (TreeNode) pluginList.next(); |
| TreeNode tagClassNode = pluginNode.findChild("tag-class"); |
| if (tagClassNode == null) { |
| // Error |
| return; |
| } |
| String tagClass = tagClassNode.getBody().trim(); |
| TreeNode pluginClassNode = pluginNode.findChild("plugin-class"); |
| if (pluginClassNode == null) { |
| // Error |
| return; |
| } |
| |
| String pluginClassStr = pluginClassNode.getBody(); |
| TagPlugin tagPlugin = null; |
| try { |
| Class pluginClass = Class.forName(pluginClassStr); |
| tagPlugin = (TagPlugin) pluginClass.newInstance(); |
| } catch (Exception e) { |
| throw new JasperException(e); |
| } |
| if (tagPlugin == null) { |
| return; |
| } |
| tagPlugins.put(tagClass, tagPlugin); |
| } |
| initialized = true; |
| } |
| |
| /** |
| * Invoke tag plugin for the given custom tag, if a plugin exists for |
| * the custom tag's tag handler. |
| * |
| * The given custom tag node will be manipulated by the plugin. |
| */ |
| private void invokePlugin(Node.CustomTag n) { |
| TagPlugin tagPlugin = (TagPlugin) |
| tagPlugins.get(n.getTagHandlerClass().getName()); |
| if (tagPlugin == null) { |
| return; |
| } |
| |
| TagPluginContext tagPluginContext = new TagPluginContextImpl(n, pageInfo); |
| n.setTagPluginContext(tagPluginContext); |
| tagPlugin.doTag(tagPluginContext); |
| } |
| |
| static class TagPluginContextImpl implements TagPluginContext { |
| private Node.CustomTag node; |
| private Node.Nodes curNodes; |
| private PageInfo pageInfo; |
| private HashMap pluginAttributes; |
| |
| TagPluginContextImpl(Node.CustomTag n, PageInfo pageInfo) { |
| this.node = n; |
| this.pageInfo = pageInfo; |
| curNodes = new Node.Nodes(); |
| n.setAtETag(curNodes); |
| curNodes = new Node.Nodes(); |
| n.setAtSTag(curNodes); |
| n.setUseTagPlugin(true); |
| pluginAttributes = new HashMap(); |
| } |
| |
| public TagPluginContext getParentContext() { |
| Node parent = node.getParent(); |
| if (! (parent instanceof Node.CustomTag)) { |
| return null; |
| } |
| return ((Node.CustomTag) parent).getTagPluginContext(); |
| } |
| |
| public void setPluginAttribute(String key, Object value) { |
| pluginAttributes.put(key, value); |
| } |
| |
| public Object getPluginAttribute(String key) { |
| return pluginAttributes.get(key); |
| } |
| |
| public boolean isScriptless() { |
| return node.getChildInfo().isScriptless(); |
| } |
| |
| public boolean isConstantAttribute(String attribute) { |
| Node.JspAttribute attr = getNodeAttribute(attribute); |
| if (attr == null) |
| return false; |
| return attr.isLiteral(); |
| } |
| |
| public String getConstantAttribute(String attribute) { |
| Node.JspAttribute attr = getNodeAttribute(attribute); |
| if (attr == null) |
| return null; |
| return attr.getValue(); |
| } |
| |
| public boolean isAttributeSpecified(String attribute) { |
| return getNodeAttribute(attribute) != null; |
| } |
| |
| public String getTemporaryVariableName() { |
| return JspUtil.nextTemporaryVariableName(); |
| } |
| |
| public void generateImport(String imp) { |
| pageInfo.addImport(imp); |
| } |
| |
| public void generateDeclaration(String id, String text) { |
| if (pageInfo.isPluginDeclared(id)) { |
| return; |
| } |
| curNodes.add(new Node.Declaration(text, node.getStart(), null)); |
| } |
| |
| public void generateJavaSource(String sourceCode) { |
| curNodes.add(new Node.Scriptlet(sourceCode, node.getStart(), |
| null)); |
| } |
| |
| public void generateAttribute(String attributeName) { |
| curNodes.add(new Node.AttributeGenerator(node.getStart(), |
| attributeName, |
| node)); |
| } |
| |
| public void dontUseTagPlugin() { |
| node.setUseTagPlugin(false); |
| } |
| |
| public void generateBody() { |
| // Since we'll generate the body anyway, this is really a nop, |
| // except for the fact that it lets us put the Java sources the |
| // plugins produce in the correct order (w.r.t the body). |
| curNodes = node.getAtETag(); |
| } |
| |
| private Node.JspAttribute getNodeAttribute(String attribute) { |
| Node.JspAttribute[] attrs = node.getJspAttributes(); |
| for (int i=0; attrs != null && i < attrs.length; i++) { |
| if (attrs[i].getName().equals(attribute)) { |
| return attrs[i]; |
| } |
| } |
| return null; |
| } |
| } |
| } |