Package org.apache.geronimo.jasper.deployment

Source Code of org.apache.geronimo.jasper.deployment.JspModuleBuilderExtension

/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.geronimo.jasper.deployment;

import java.io.File;
import java.io.IOException;
import java.net.JarURLConnection;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import javax.xml.namespace.QName;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.geronimo.common.DeploymentException;
import org.apache.geronimo.deployment.ModuleIDBuilder;
import org.apache.geronimo.deployment.service.EnvironmentBuilder;
import org.apache.geronimo.deployment.xmlbeans.XmlBeansUtil;
import org.apache.geronimo.gbean.AbstractName;
import org.apache.geronimo.gbean.GBeanData;
import org.apache.geronimo.gbean.GBeanInfo;
import org.apache.geronimo.gbean.GBeanInfoBuilder;
import org.apache.geronimo.j2ee.annotation.Holder;
import org.apache.geronimo.j2ee.deployment.EARContext;
import org.apache.geronimo.j2ee.deployment.Module;
import org.apache.geronimo.j2ee.deployment.ModuleBuilderExtension;
import org.apache.geronimo.j2ee.deployment.NamingBuilder;
import org.apache.geronimo.j2ee.deployment.WebModule;
import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
import org.apache.geronimo.jasper.JasperServletContextCustomizer;
import org.apache.geronimo.kernel.GBeanAlreadyExistsException;
import org.apache.geronimo.kernel.Naming;
import org.apache.geronimo.kernel.config.Configuration;
import org.apache.geronimo.kernel.config.ConfigurationStore;
import org.apache.geronimo.kernel.repository.Environment;
import org.apache.geronimo.schema.SchemaConversionUtils;
import org.apache.geronimo.xbeans.javaee.FullyQualifiedClassType;
import org.apache.geronimo.xbeans.javaee.JspConfigType;
import org.apache.geronimo.xbeans.javaee.ListenerType;
import org.apache.geronimo.xbeans.javaee.TagType;
import org.apache.geronimo.xbeans.javaee.TaglibDocument;
import org.apache.geronimo.xbeans.javaee.TaglibType;
import org.apache.geronimo.xbeans.javaee.TldTaglibType;
import org.apache.geronimo.xbeans.javaee.WebAppType;
import org.apache.xbean.finder.ClassFinder;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;

/**
* This JSP module builder extension is meant to find all the TLD descriptor files associated with a
* deployable artifact, search those TLD files for listeners, search those listeners for
* annotations, and ultimately create a ClassFinder using those annoated classes (for later
* processing by the various naming builders)
*
* @version $Rev $Date
*/
public class JspModuleBuilderExtension implements ModuleBuilderExtension {

    private static final Log log = LogFactory.getLog(JspModuleBuilderExtension.class);

    private final Environment defaultEnvironment;
    private final NamingBuilder namingBuilders;

    private static final QName TLIB_VERSION = new QName(SchemaConversionUtils.JAVAEE_NAMESPACE, "tlib-version");
    private static final QName SHORT_NAME = new QName(SchemaConversionUtils.JAVAEE_NAMESPACE, "short-name");
    private static final QName TAG_CLASS = new QName(SchemaConversionUtils.JAVAEE_NAMESPACE, "tag-class");
    private static final QName TEI_CLASS = new QName(SchemaConversionUtils.JAVAEE_NAMESPACE, "tei-class");
    private static final QName BODY_CONTENT = new QName(SchemaConversionUtils.JAVAEE_NAMESPACE, "body-content");

    private static final String SCHEMA_LOCATION_URL = "http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd";
    private static final String VERSION = "2.1";

    public JspModuleBuilderExtension(Environment defaultEnvironment, NamingBuilder namingBuilders) {
        this.defaultEnvironment = defaultEnvironment;
        this.namingBuilders = namingBuilders;
    }

    public void createModule(Module module, Object plan, JarFile moduleFile, String targetPath, URL specDDUrl, Environment environment, Object moduleContextInfo, AbstractName earName, Naming naming, ModuleIDBuilder idBuilder) throws DeploymentException {
    }

    public void installModule(JarFile earFile, EARContext earContext, Module module, Collection configurationStores, ConfigurationStore targetConfigurationStore, Collection repository) throws DeploymentException {
    }

    public void initContext(EARContext earContext, Module module, ClassLoader cl) throws DeploymentException {
    }

    public void addGBeans(EARContext earContext, Module module, ClassLoader cl, Collection repository) throws DeploymentException {
        if (!(module instanceof WebModule)) {
            //not a web module, nothing to do
            return;
        }
        //TODO Only merge if we detect jsps???
        EnvironmentBuilder.mergeEnvironments(module.getEnvironment(), defaultEnvironment);

        WebModule webModule = (WebModule) module;
        WebAppType webApp = (WebAppType) webModule.getSpecDD();

        EARContext moduleContext = module.getEarContext();
        Map sharedContext = module.getSharedContext();

        GBeanData webAppData = (GBeanData) sharedContext.get(WebModule.WEB_APP_DATA);

        AbstractName moduleName = moduleContext.getModuleName();
        Map<NamingBuilder.Key, Object> buildingContext = new HashMap<NamingBuilder.Key, Object>();
        buildingContext.put(NamingBuilder.GBEAN_NAME_KEY, moduleName);

        //use the same jndi context as the web app
        Map compContext = NamingBuilder.JNDI_KEY.get(sharedContext);
        buildingContext.put(NamingBuilder.JNDI_KEY, compContext);

        //use the same holder object as the web app.
        Holder holder = NamingBuilder.INJECTION_KEY.get(sharedContext);
        buildingContext.put(NamingBuilder.INJECTION_KEY, holder);

        XmlObject jettyWebApp = webModule.getVendorDD();

        Configuration earConfiguration = earContext.getConfiguration();

        Set<String> listenerNames = new HashSet<String>();

        ClassFinder classFinder = createJspClassFinder(webApp, webModule, listenerNames);
        webModule.setClassFinder(classFinder);

        namingBuilders.buildNaming(webApp, jettyWebApp, webModule, buildingContext);

        //only try to install it if reference will work.
        //Some users (tomcat?) may have back doors into jasper that make adding this gbean unnecessary.
        GBeanInfo webAppGBeanInfo = webAppData.getGBeanInfo();
        if (webAppGBeanInfo.getReference("ContextCustomizer") != null) {
            AbstractName jspLifecycleName = moduleContext.getNaming().createChildName(moduleName, "jspLifecycleProvider", NameFactory.GERONIMO_SERVICE);
            GBeanData gbeanData = new GBeanData(jspLifecycleName, JasperServletContextCustomizer.GBEAN_INFO);
            gbeanData.setAttribute("holder", holder);

            try {
                moduleContext.addGBean(gbeanData);
            } catch (GBeanAlreadyExistsException e) {
                throw new DeploymentException("Duplicate jspLifecycleProvider", e);
            }

            webAppData.setReferencePattern("ContextCustomizer", jspLifecycleName);
        }
        //add listeners if possible
        //we may need to add them in another way for tomcat
        Object value = webAppData.getAttribute("listenerClassNames");
        if (value instanceof Collection) {
            ((Collection<String>) value).addAll(listenerNames);
        }
    }

    protected ClassFinder createJspClassFinder(WebAppType webApp, WebModule webModule, Set<String> listenerNames) throws DeploymentException {
        List<URL> urls = getTldFiles(webApp, webModule);
        List<Class> classes = getListenerClasses(webApp, webModule, urls, listenerNames);
        return new ClassFinder(classes);
    }


    /**
     * getTldFiles(): Find all the TLD files in the web module being deployed
     *
     * <p>Locations to search for these TLD file(s) (matches the precedence search order for TLD
     * files per the JSP specs):
     * <ol>
     *      <li>web.xml <taglib> entries
     *      <li>TLD(s) in JAR files in WEB-INF/lib
     *      <li>TLD(s) under WEB-INF
     *      <li>All TLD files in all META-INF(s)
     * </ol>
     *
     * @param webApp    spec DD for module
     * @param webModule module being deployed
     * @return list of the URL(s) for the TLD files
     * @throws DeploymentException if there's a problem finding a tld file
     */
    private List<URL> getTldFiles(WebAppType webApp, WebModule webModule) throws DeploymentException {
        log.debug("getTldFiles( " + webApp.toString() + "," + webModule.getName() + " ): Entry");

        List<URL> tldURLs = new ArrayList<URL>();

        // 1. web.xml <taglib> entries
        JspConfigType[] jspConfigs = webApp.getJspConfigArray();
        for (JspConfigType jspConfig : jspConfigs) {
            TaglibType[] taglibs = jspConfig.getTaglibArray();
            for (TaglibType taglib : taglibs) {
                String uri = taglib.getTaglibUri().getStringValue().trim();
                String location = taglib.getTaglibLocation().getStringValue().trim();
                if (!location.equals("")) {
                    if (location.startsWith("/")) {
                        location = location.substring(1);
                    }
                    try {
                        File targetFile = webModule.getEarContext().getTargetFile(createURI(location));
                        if (targetFile!=null) {
                            tldURLs.add(targetFile.toURL());
                        }
                    }
                    catch (MalformedURLException mfe) {
                        throw new DeploymentException("Could not locate TLD file specified in <taglib>: URI: " + uri + " Location: " + location + " " + mfe.getMessage(), mfe);
                    }
                    catch (URISyntaxException use) {
                        throw new DeploymentException("Could not locate TLD file specified in <taglib>: URI: " + uri + " Location: " + location + " " + use.getMessage(), use);
                    }
                }
            }
        }

        // 2. TLD(s) in JAR files in WEB-INF/lib
        // 3. TLD(s) under WEB-INF
        List<URL> tempURLs = scanModule(webModule);
        for (URL webInfURL : tempURLs) {
            tldURLs.add(webInfURL);
        }

        // 4. All TLD files in all META-INF(s)
        tempURLs.clear();
        try {
            Enumeration<URL> enumURLs = webModule.getEarContext().getClassLoader().getResources("META-INF");
            while (enumURLs.hasMoreElements()) {
                URL enumURL = enumURLs.nextElement();
                tempURLs = scanDirectory(enumURL);
                for (URL metaInfURL : tempURLs) {
                    tldURLs.add(metaInfURL);
                }
                tempURLs.clear();
            }
        }
        catch (IOException ioe) {
            throw new DeploymentException("Could not locate TLD files located in META-INF(s) " + ioe.getMessage(), ioe);
        }

        log.debug("getTldFiles() Exit: URL[" + tldURLs.size() + "]: " + tldURLs.toString());
        return tldURLs;
    }


    /**
     * scanModule(): Scan the module being deployed for JAR files or TLD files in the WEB-INF
     * directory
     *
     * @param webModule module being deployed
     * @return list of the URL(s) for the TLD files in the module
     * @throws DeploymentException if module cannot be scanned
     */
    private List<URL> scanModule(WebModule webModule) throws DeploymentException {
        log.debug("scanModule( " + webModule.getName() + " ): Entry");

        List<URL> modURLs = new ArrayList<URL>();
        try {
            Enumeration<JarEntry> entries = webModule.getModuleFile().entries();
            while (entries.hasMoreElements()) {
                JarEntry jarEntry = entries.nextElement();
                if (jarEntry.getName().startsWith("WEB-INF/") && jarEntry.getName().endsWith(".tld")) {
                    File targetFile = webModule.getEarContext().getTargetFile(createURI(jarEntry.getName()));
                    if (targetFile!=null) {
                        modURLs.add(targetFile.toURL());
                    }
                }
                if (jarEntry.getName().startsWith("WEB-INF/lib/") && jarEntry.getName().endsWith(".jar")) {
                    File targetFile = webModule.getEarContext().getTargetFile(createURI(jarEntry.getName()));
                    List<URL> jarUrls = scanJAR(new JarFile(targetFile), null);
                    for (URL jarURL : jarUrls) {
                        modURLs.add(jarURL);
                    }
                }
            }
        }
        catch (IOException ioe) {
            throw new DeploymentException("Could not scan module for TLD files: " + webModule.getName() + " " + ioe.getMessage(), ioe);
        }
        catch (Exception e) {
            throw new DeploymentException("Could not scan module for TLD files: " + webModule.getName() + " " + e.getMessage(), e);
        }

        log.debug("scanModule() Exit: URL[" + modURLs.size() + "]: " + modURLs.toString());
        return modURLs;
    }


    /**
     * scanJAR(): Scan a JAR files looking for all TLD
     *
     * @param jarFile jar file to scan
     * @param prefix  Optional prefix to limit the search to a specific subdirectory in the JAR file
     * @return list of the URL(s) for the TLD files in the JAR file
     * @throws DeploymentException if jar file cannot be scanned
     */
    private List<URL> scanJAR(JarFile jarFile, String prefix) throws DeploymentException {
        log.debug("scanJAR( " + jarFile.getName() + " ): Entry");

        List<URL> jarURLs = new ArrayList<URL>();
        try {
            Enumeration<JarEntry> entries = jarFile.entries();
            while (entries.hasMoreElements()) {
                JarEntry jarEntry = entries.nextElement();
                URL tempURL = null;
                if (prefix != null) {
                    if (jarEntry.getName().endsWith(".tld") && jarEntry.getName().startsWith(prefix)) {
                        tempURL = new URL("jar:file:" + jarFile.getName() + "!/" + jarEntry.getName());
                    }
                } else {
                    if (jarEntry.getName().endsWith(".tld")) {
                        tempURL = new URL("jar:file:" + jarFile.getName() + "!/" + jarEntry.getName());
                    }
                }
                if (tempURL != null) {
                    jarURLs.add(tempURL);
                }
            }
        }
        catch (MalformedURLException mfe) {
            throw new DeploymentException("Could not scan JAR file for TLD files: " + jarFile.getName() + " " + mfe.getMessage(), mfe);
        }
        catch (Exception e) {
            throw new DeploymentException("Could not scan JAR file for TLD files: " + jarFile.getName() + " " + e.getMessage(), e);
        }

        log.debug("scanJAR() Exit: URL[" + jarURLs.size() + "]: " + jarURLs.toString());
        return jarURLs;
    }


    /**
     * scanDirectory(): Scan a directory for all TLD files
     *
     * @param url URL for the directory to be scanned
     * @return list of the URL(s) for the TLD files in the directory
     * @throws DeploymentException if directory cannot be scanned
     */
    private List<URL> scanDirectory(URL url) throws DeploymentException {
        log.debug("scanDirectory( " + url.toString() + " ): Entry");

        List<URL> dirURLs = new ArrayList<URL>();
        File directory;
        if (url != null) {
            if (url.toString().startsWith("jar:file:")) {
                try {
                    JarURLConnection jarConnection = (JarURLConnection) url.openConnection();
                    URL urlJC = jarConnection.getJarFileURL();
                    URI baseURI = createURI(urlJC.toString());
                    directory = new File(baseURI);
                    if (directory.isDirectory()) {
                        if (directory.canRead()) {
                            JarFile temp = new JarFile(directory);
                            List<URL> tempURLs = scanJAR(temp, "META-INF");
                            for (URL jarURL : tempURLs) {
                                dirURLs.add(jarURL);
                            }
                        } else {
                            log.warn("Cannot read JAR file: " + url.toString());
                        }
                    }
                }
                catch (Exception e) {
                    throw new DeploymentException("Could not scan directory for TLD files: " + url.toString() + " " + e.getMessage(), e);
                }
            } else if (url.toString().startsWith("file:")) {
                try {
                    URI baseURI = createURI(url.toString());
                    directory = new File(baseURI);
                    if (directory.isDirectory() && directory.canRead()) {
                        File[] children = directory.listFiles();
                        for (File child : children) {
                            if (child.getName().endsWith(".tld")) {
                                dirURLs.add(child.toURL());
                            }
                        }
                    } else {
                        log.warn("Cannot read directory: " + url.toString());
                    }
                }
                catch (Exception e) {
                    throw new DeploymentException("Could not scan directory for TLD files: " + url.toString() + " " + e.getMessage(), e);
                }
            } else if (url.toString().startsWith("jar:")) {
                log.warn("URL type not accounted for: " + url.toString());
            }
        }

        log.debug("scanDirectory() Exit: URL[" + dirURLs.size() + "]: " + dirURLs.toString());
        return dirURLs;
    }


    private List<Class> getListenerClasses(WebAppType webApp, WebModule webModule, List<URL> urls, Set<String> listenerNames) throws DeploymentException {
        log.debug("getListenerClasses( " + webApp.toString() + "," + '\n' +
                webModule.getName() + " ): Entry");

        // Get the classloader from the module's EARContext
        ClassLoader classLoader = webModule.getEarContext().getClassLoader();
        List<Class> classes = new ArrayList<Class>();

        for (URL url : urls) {
            parseTldFile(url, classLoader, classes, listenerNames);
        }

        log.debug("getListenerClasses() Exit: Classes[" + classes.size() + "]: " + classes.toString());
        return classes;
    }


    private void parseTldFile(URL url, ClassLoader classLoader, List<Class> classes, Set<String> listenerNames) throws DeploymentException {
        log.debug("parseTLDFile( " + url.toString() + " ): Entry");

        try {
            XmlObject xml = XmlBeansUtil.parse(url, null);
            TaglibDocument tld = convertToTaglibSchema(xml);
            TldTaglibType tl = tld.getTaglib();

            // Get all the listeners from the TLD file
            ListenerType[] listeners = tl.getListenerArray();
            for (ListenerType listener : listeners) {
                FullyQualifiedClassType cls = listener.getListenerClass();
                String className = cls.getStringValue().trim();
                listenerNames.add(className);
                try {
                    Class clas = classLoader.loadClass(className);
                    classes.add(clas);
                }
                catch (ClassNotFoundException e) {
                    log.warn("JspModuleBuilderExtension: Could not load listener class: " + className + " mentioned in TLD file at " + url.toString());
                }
            }

            // Get all the tags from the TLD file
            TagType[] tags = tl.getTagArray();
            for (TagType tag : tags) {
                FullyQualifiedClassType cls = tag.getTagClass();
                String className = cls.getStringValue().trim();
                try {
                    Class clas = classLoader.loadClass(className);
                    classes.add(clas);
                }
                catch (ClassNotFoundException e) {
                    log.warn("JspModuleBuilderExtension: Could not load tag class: " + className + " mentioned in TLD file at " + url.toString());
                }
            }
        }
        catch (XmlException xmle) {
            throw new DeploymentException("Could not parse TLD file at " + url.toString(), xmle);
        }
        catch (IOException ioe) {
            throw new DeploymentException("Could not find TLD file at " + url.toString(), ioe);
        }

        log.debug("parseTLDFile(): Exit");
    }


    /**
     * convertToTaglibSchema(): Convert older TLD files based on the 1.1 and 1.2 DTD or the 2.0 XSD
     * schemas
     *
     * <p><strong>Note(s):</strong>
     * <ul>
     *      <li>Those tags from the 1.1 and 1.2 DTD that are no longer valid (e.g., jsp-version) are
     *      removed
     *      <li>Valid  tags from the 1.1 and 1.2 DTD are converted (e.g., tlibversion to
     *      tlib-version)
     *      <li>The <taglib> root and the <tag> root elements are reordered as necessary (i.e.,
     *      description, display-name)
     *      <li>The <rtexprvalue> tag is inserted in the &lt;attribute> tag if necessary since it was
     *      not required to preceed <type> in 2.0 schema. Default value of false is used.
     * </ul>
     *
     * @param xmlObject possibly old-style tag lib document
     * @return converted TagLibDocument in the new shiny schema
     * @throws XmlException if something goes horribly wrong
     */
    protected static TaglibDocument convertToTaglibSchema(XmlObject xmlObject) throws XmlException {
        log.debug("convertToTaglibSchema( " + xmlObject.toString() + " ): Entry");

        XmlCursor cursor = xmlObject.newCursor();
        XmlCursor moveable = xmlObject.newCursor();
        try {
            cursor.toStartDoc();
            cursor.toFirstChild();
            if (SchemaConversionUtils.JAVAEE_NAMESPACE.equals(cursor.getName().getNamespaceURI())) {
                log.debug("Nothing to do");
            }
            else if (SchemaConversionUtils.J2EE_NAMESPACE.equals(cursor.getName().getNamespaceURI())) {
                log.debug("Converting XSD 2.0 to 2.1 schema");
                SchemaConversionUtils.convertSchemaVersion(cursor, SchemaConversionUtils.JAVAEE_NAMESPACE, SCHEMA_LOCATION_URL, VERSION);
                cursor.toStartDoc();
                cursor.toChild(SchemaConversionUtils.JAVAEE_NAMESPACE, "taglib");
                cursor.toFirstChild();
                do {
                    String name = cursor.getName().getLocalPart();
                    if ("tag".equals(name)) {
                        cursor.push();
                        cursor.toFirstChild();
                        SchemaConversionUtils.convertToDescriptionGroup(SchemaConversionUtils.JAVAEE_NAMESPACE, cursor, moveable);
                        do {
                            name = cursor.getName().getLocalPart();
                            boolean rtexprvalueFound = false;
                            boolean typeFound = false;
                            if ("attribute".equals(name)) {
                                cursor.push();
                                cursor.toFirstChild();
                                do {
                                    name = cursor.getName().getLocalPart();
                                    if ("rtexprvalue".equals(name)) {
                                        rtexprvalueFound = true;
                                    }
                                    if ("type".equals(name)) {
                                        typeFound = true;
                                    }
                                } while (cursor.toNextSibling());
                                cursor.pop();
                                if (typeFound && !rtexprvalueFound) {
                                    //--------------------------------------------------------------
                                    // Handle the case where the <type> tag must now be preceded by
                                    // the <rtexprvalue> tag in the 2.1 schema. Cases are:
                                    // 1: Only type found:
                                    //      We are currently positioned directly after the attribute
                                    //      tag (via the pop) so just insert the rtexprvalue tag
                                    //      with the default value. The tags will be properly
                                    //      ordered below.
                                    // 2: Both type and rtexprvalue found:
                                    //      The tags will be properly ordered below with the
                                    //      convertToAttributeGroup() call, so nothing to do
                                    // 3: Only rtexprvalue found:
                                    //      Nothing to do
                                    // 4: Neither found:
                                    //      Nothing to do
                                    //--------------------------------------------------------------
                                    cursor.push();
                                    cursor.toFirstChild();
                                    cursor.insertElementWithText("rtexprvalue", SchemaConversionUtils.JAVAEE_NAMESPACE, "false");
                                    cursor.pop();
                                }
                                cursor.push();
                                cursor.toFirstChild();
                                SchemaConversionUtils.convertToTldAttribute(SchemaConversionUtils.JAVAEE_NAMESPACE, cursor, moveable);
                                cursor.pop();
                            }
                        } while (cursor.toNextSibling());
                        cursor.pop();
                        // Do this conversion last after the other tags have been converted
                        SchemaConversionUtils.convertToTldTag(SchemaConversionUtils.JAVAEE_NAMESPACE, cursor, moveable);
                    }
                } while (cursor.toNextSibling());
            }
            else {
                log.debug("Converting DTD to 2.1 schema");
                SchemaConversionUtils.convertToSchema(cursor, SchemaConversionUtils.JAVAEE_NAMESPACE, SCHEMA_LOCATION_URL, VERSION);
                cursor.toStartDoc();
                cursor.toChild(SchemaConversionUtils.JAVAEE_NAMESPACE, "taglib");
                cursor.toFirstChild();
                SchemaConversionUtils.convertToDescriptionGroup(SchemaConversionUtils.JAVAEE_NAMESPACE, cursor, moveable);
                do {
                    String name = cursor.getName().getLocalPart();
                    if ("jsp-version".equals(name) ||
                        "jspversion".equals(name) ||
                        "info".equals(name)) {
                        cursor.removeXmlContents();
                        cursor.removeXml();
                    }
                    if ("tlibversion".equals(name)) {
                        cursor.setName(TLIB_VERSION);
                    }
                    if ("tlibversion".equals(name)) {
                        cursor.setName(TLIB_VERSION);
                    }
                    if ("shortname".equals(name)) {
                        cursor.setName(SHORT_NAME);
                    }
                    if ("tag".equals(name)) {
                        cursor.push();
                        cursor.toFirstChild();
                        SchemaConversionUtils.convertToDescriptionGroup(SchemaConversionUtils.JAVAEE_NAMESPACE, cursor, moveable);
                        boolean bodyContentFound = false;
                        do {
                            name = cursor.getName().getLocalPart();
                            if ("tagclass".equals(name)) {
                                cursor.setName(TAG_CLASS);
                            }
                            if ("teiclass".equals(name)) {
                                cursor.setName(TEI_CLASS);
                            }
                            if ("bodycontent".equals(name)) {
                                cursor.setName(BODY_CONTENT);
                                bodyContentFound = true;
                            }
                            if ("body-content".equals(name)) {
                                bodyContentFound = true;
                            }
                            if ("attribute".equals(name)) {
                                cursor.push();
                                cursor.toFirstChild();
                                SchemaConversionUtils.convertToTldAttribute(SchemaConversionUtils.JAVAEE_NAMESPACE, cursor, moveable);
                                cursor.pop();
                            }
                            if ("variable".equals(name)) {
                                cursor.push();
                                cursor.toFirstChild();
                                SchemaConversionUtils.convertToTldVariable(SchemaConversionUtils.JAVAEE_NAMESPACE, cursor, moveable);
                                cursor.pop();
                            }
                            if ("info".equals(name)) {
                                cursor.removeXmlContents();
                                cursor.removeXml();
                            }
                        } while (cursor.toNextSibling());
                        cursor.pop();
                        if (!bodyContentFound) {
                            //--------------------------------------------------------------
                            // Handle the case where the <body-content> tag is missing. We
                            // are currently positioned directly after the <tag> attribute
                            // (via the pop) so just insert the <body-content> tag with the
                            // default value. The tags will be properly ordered below.
                            //--------------------------------------------------------------
                            cursor.push();
                            cursor.toFirstChild();
                            cursor.insertElementWithText("body-content", SchemaConversionUtils.JAVAEE_NAMESPACE, "scriptless");
                            cursor.pop();
                        }
                        // Do this conversion last after the other tags have been converted
                        cursor.push();
                        cursor.toFirstChild();
                        SchemaConversionUtils.convertToTldTag(SchemaConversionUtils.JAVAEE_NAMESPACE, cursor, moveable);
                        cursor.pop();
                    }
                    if ("validator".equals(name)) {
                        cursor.push();
                        cursor.toFirstChild();
                        SchemaConversionUtils.convertToTldValidator(SchemaConversionUtils.JAVAEE_NAMESPACE, cursor, moveable);
                        do {
                            name = cursor.getName().getLocalPart();
                            if ("init-param".equals(name)) {
                                cursor.push();
                                cursor.toFirstChild();
                                SchemaConversionUtils.convertToTldInitParam(SchemaConversionUtils.JAVAEE_NAMESPACE, cursor, moveable);
                                cursor.pop();
                            }
                        } while (cursor.toNextSibling());
                        cursor.pop();
                    }
                } while (cursor.toNextSibling());
            }
        }
        finally {
            cursor.dispose();
            moveable.dispose();
        }
        XmlObject result = xmlObject.changeType(TaglibDocument.type);
        if (result != null) {
            try {
                XmlBeansUtil.validateDD(result);
            } catch (XmlException e) {
                log.warn("Invalid transformed taglib", e);
            }
            log.debug("convertToTaglibSchema( " + result.toString() + " ): Exit 1");
            return (TaglibDocument) result;
        }
        try {
            XmlBeansUtil.validateDD(xmlObject);
        } catch (XmlException e) {
            log.warn("Invalid transformed taglib", e);
        }
        log.debug("convertToTaglibSchema( " + xmlObject.toString() + " ): Exit 2");
        return (TaglibDocument) xmlObject;
    }


    private URI createURI(String path) throws URISyntaxException {
        path = path.replaceAll(" ", "%20");
        return new URI(path);
    }

    public static final GBeanInfo GBEAN_INFO;

    static {
        GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(JspModuleBuilderExtension.class, NameFactory.MODULE_BUILDER);
        infoBuilder.addAttribute("defaultEnvironment", Environment.class, true, true);
        infoBuilder.addReference("NamingBuilders", NamingBuilder.class, NameFactory.MODULE_BUILDER);

        infoBuilder.setConstructor(new String[]{
                "defaultEnvironment",
                "NamingBuilders"});
        GBEAN_INFO = infoBuilder.getBeanInfo();
    }

    public static GBeanInfo getGBeanInfo() {
        return GBEAN_INFO;
    }
}
TOP

Related Classes of org.apache.geronimo.jasper.deployment.JspModuleBuilderExtension

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.