All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.faces.config.processor.FaceletTaglibConfigProcessor Maven / Gradle / Ivy

There is a newer version: 4.1.1
Show newest version
/*
 * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package com.sun.faces.config.processor;

import static java.text.MessageFormat.format;
import static java.util.logging.Level.FINE;
import static java.util.logging.Level.WARNING;

import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.sun.faces.application.ApplicationAssociate;
import com.sun.faces.config.ConfigurationException;
import com.sun.faces.config.manager.documents.DocumentInfo;
import com.sun.faces.facelets.compiler.Compiler;
import com.sun.faces.facelets.tag.TagLibrary;
import com.sun.faces.facelets.tag.TagLibraryImpl;
import com.sun.faces.facelets.tag.faces.CompositeComponentTagLibrary;
import com.sun.faces.facelets.util.ReflectionUtil;
import com.sun.faces.util.FacesLogger;

import jakarta.faces.FacesException;
import jakarta.faces.context.FacesContext;
import jakarta.servlet.ServletContext;

/**
 * 

* This ConfigProcessor handles all elements defined under /faces-taglib. *

*/ public class FaceletTaglibConfigProcessor extends AbstractConfigProcessor { private static final Logger LOGGER = FacesLogger.CONFIG.getLogger(); /** *

* /facelet-taglib/library-class *

*/ private static final String LIBRARY_CLASS = "library-class"; /** *

* /facelet-taglib/namespace *

*/ private static final String TAGLIB_NAMESPACE = "namespace"; /** *

* /facelet-taglib/tag *

*/ private static final String TAG = "tag"; /** *

* /facelet-taglib/function *

*/ private static final String FUNCTION = "function"; /** *

* /facelet-taglib/tag/tag-name *

*/ private static final String TAG_NAME = "tag-name"; /** *

* /facelet-taglib/tag/component *

*/ private static final String COMPONENT = "component"; /** *

* /facelet-taglib/tag/validator *

*/ private static final String VALIDATOR = "validator"; /** *

* /facelet-taglib/tag/converter *

*/ private static final String CONVERTER = "converter"; /** *

* /facelet-taglib/tag/behavior *

*/ private static final String BEHAVIOR = "behavior"; /** *

* /facelet-taglib/tag/source *

*/ private static final String SOURCE = "source"; /** *

* /facelet-taglib/tag/resource-id *

*/ private static final String RESOURCE_ID = "resource-id"; /** *

*

    *
  • /facelet-taglib/tag/tag-handler
  • *
  • /facelet-taglib/tag/converter/handler-class
  • *
  • /facelet-taglib/tag/validator/handler-class
  • *
  • /facelet-taglib/tag/component/handler-class
  • *
*

*/ private static final String HANDLER_CLASS = "handler-class"; /** *

* /facelet-taglib/tag/validator/validator-id *

*/ private static final String VALIDATOR_ID = "validator-id"; /** *

* /facelet-taglib/tag/converter/converter-id *

*/ private static final String CONVERTER_ID = "converter-id"; /** *

* /facelet-taglib/tag/behavior/behavior-id *

*/ private static final String BEHAVIOR_ID = "behavior-id"; /** *

* /facelet-taglib/tag/component/component-type *

*/ private static final String COMPONENT_TYPE = "component-type"; /** *

* /facelet-taglib/tag/component/renderer-type *

*/ private static final String RENDERER_TYPE = "renderer-type"; /** *

* /facelet-taglib/tag/function/function-name *

*/ private static final String FUNCTION_NAME = "function-name"; /** *

* /facelet-taglib/tag/function/function-class *

*/ private static final String FUNCTION_CLASS = "function-class"; /** *

* /facelet-taglib/tag/function/function-signature *

*/ private static final String FUNCTION_SIGNATURE = "function-signature"; /** *

* /facelet-taglib/composite-library-name *

*/ private static final String COMPOSITE_LIBRARY_NAME = "composite-library-name"; // -------------------------------------------- Methods from ConfigProcessor @Override public void process(ServletContext sc, FacesContext facesContext, DocumentInfo[] documentInfos) throws Exception { ApplicationAssociate associate = ApplicationAssociate.getInstance(facesContext.getExternalContext()); Compiler compiler = associate.getCompiler(); for (int i = 0, length = documentInfos.length; i < length; i++) { if (LOGGER.isLoggable(FINE)) { LOGGER.log(FINE, format("Processing facelet-taglibrary document: ''{0}''", documentInfos[i].getSourceURI())); } Document document = documentInfos[i].getDocument(); String namespace = document.getDocumentElement().getNamespaceURI(); Element documentElement = document.getDocumentElement(); NodeList libraryClass = documentElement.getElementsByTagNameNS(namespace, LIBRARY_CLASS); if (libraryClass != null && libraryClass.getLength() > 0) { processTaglibraryClass(sc, facesContext, libraryClass, compiler); } else { processTagLibrary(sc, facesContext, documentElement, namespace, compiler); } } } // --------------------------------------------------------- Private Methods private void processTaglibraryClass(ServletContext servletContext, FacesContext facesContext, NodeList libraryClass, Compiler compiler) { Node n = libraryClass.item(0); String className = getNodeText(n); TagLibrary taglib = (TagLibrary) createInstance(servletContext, facesContext, className, n); compiler.addTagLibrary(taglib); } private void processTagLibrary(ServletContext sc, FacesContext facesContext, Element documentElement, String namespace, Compiler compiler) { NodeList children = documentElement.getChildNodes(); if (children != null && children.getLength() > 0) { String taglibNamespace = null; String compositeLibraryName = null; for (int i = 0, ilen = children.getLength(); i < ilen; i++) { Node n = children.item(i); if (n.getLocalName() != null) { switch (n.getLocalName()) { case TAGLIB_NAMESPACE: taglibNamespace = getNodeText(n); break; case COMPOSITE_LIBRARY_NAME: compositeLibraryName = getNodeText(n); break; } } } TagLibraryImpl taglibrary; if (compositeLibraryName != null) { taglibrary = new CompositeComponentTagLibrary(taglibNamespace, compositeLibraryName); compiler.addTagLibrary(taglibrary); } else { taglibrary = new TagLibraryImpl(taglibNamespace); } NodeList tags = documentElement.getElementsByTagNameNS(namespace, TAG); processTags(sc, facesContext, documentElement, tags, taglibrary); NodeList functions = documentElement.getElementsByTagNameNS(namespace, FUNCTION); processFunctions(sc, facesContext, functions, taglibrary); compiler.addTagLibrary(taglibrary); } } private void processTags(ServletContext servletContext, FacesContext facesContext, Element documentElement, NodeList tags, TagLibraryImpl taglibrary) { if (tags != null && tags.getLength() > 0) { for (int i = 0, ilen = tags.getLength(); i < ilen; i++) { Node tagNode = tags.item(i); NodeList children = tagNode.getChildNodes(); String tagName = null; NodeList component = null; NodeList converter = null; NodeList validator = null; NodeList behavior = null; Node source = null; Node handlerClass = null; for (int j = 0, jlen = children.getLength(); j < jlen; j++) { Node n = children.item(j); // Process the nodes to see what children we have if (n.getLocalName() != null) { switch (n.getLocalName()) { case TAG_NAME: tagName = getNodeText(n); break; case COMPONENT: component = n.getChildNodes(); break; case CONVERTER: converter = n.getChildNodes(); break; case VALIDATOR: validator = n.getChildNodes(); break; case BEHAVIOR: behavior = n.getChildNodes(); break; case SOURCE: source = n; break; case HANDLER_CLASS: handlerClass = n; break; } } } if (component != null) { processComponent(servletContext, facesContext, documentElement, component, taglibrary, tagName); } else if (converter != null) { processConverter(servletContext, facesContext, converter, taglibrary, tagName); } else if (validator != null) { processValidator(servletContext, facesContext, validator, taglibrary, tagName); } else if (behavior != null) { processBehavior(servletContext, facesContext, behavior, taglibrary, tagName); } else if (source != null) { processSource(documentElement, source, taglibrary, tagName); } else if (handlerClass != null) { processHandlerClass(servletContext, facesContext, handlerClass, taglibrary, tagName); } } } } private void processBehavior(ServletContext sc, FacesContext facesContext, NodeList behavior, TagLibraryImpl taglibrary, String tagName) { if (behavior != null && behavior.getLength() > 0) { String behaviorId = null; String handlerClass = null; for (int i = 0, ilen = behavior.getLength(); i < ilen; i++) { Node n = behavior.item(i); if (n.getLocalName() != null) { switch (n.getLocalName()) { case BEHAVIOR_ID: behaviorId = getNodeText(n); break; case HANDLER_CLASS: handlerClass = getNodeText(n); break; } } } if (handlerClass != null) { try { Class clazz = loadClass(sc, facesContext, handlerClass, this, null); taglibrary.putBehavior(tagName, behaviorId, clazz); } catch (ClassNotFoundException e) { throw new ConfigurationException(e); } } else { taglibrary.putBehavior(tagName, behaviorId); } } } private void processHandlerClass(ServletContext sc, FacesContext facesContext, Node handlerClass, TagLibraryImpl taglibrary, String name) { String className = getNodeText(handlerClass); if (className == null) { throw new ConfigurationException("The tag named " + name + " from namespace " + taglibrary.getNamespace() + " has a null handler-class defined"); } try { Class clazz; try { clazz = loadClass(sc, facesContext, className, this, null); taglibrary.putTagHandler(name, clazz); } catch (NoClassDefFoundError defNotFound) { String message = defNotFound.toString(); if (message.contains("com/sun/facelets/") || message.contains("com.sun.facelets.")) { if (LOGGER.isLoggable(WARNING)) { LOGGER.log(WARNING, "faces.config.legacy.facelet.warning", new Object[] { handlerClass, }); } } else { throw defNotFound; } } } catch (ClassNotFoundException cnfe) { throw new ConfigurationException(cnfe); } } private void processSource(Element documentElement, Node source, TagLibraryImpl taglibrary, String name) { String docURI = documentElement.getOwnerDocument().getDocumentURI(); String s = getNodeText(source); try { URL url = new URL(new URL(docURI), s); taglibrary.putUserTag(name, url); } catch (MalformedURLException e) { throw new FacesException(e); } } private void processResourceId(Element documentElement, Node compositeSource, TagLibraryImpl taglibrary, String name) { String resourceId = getNodeText(compositeSource); taglibrary.putCompositeComponentTag(name, resourceId); } private void processValidator(ServletContext sc, FacesContext facesContext, NodeList validator, TagLibraryImpl taglibrary, String name) { if (validator != null && validator.getLength() > 0) { String validatorId = null; String handlerClass = null; for (int i = 0, ilen = validator.getLength(); i < ilen; i++) { Node n = validator.item(i); if (n.getLocalName() != null) { switch (n.getLocalName()) { case VALIDATOR_ID: validatorId = getNodeText(n); break; case HANDLER_CLASS: handlerClass = getNodeText(n); break; } } } if (handlerClass != null) { try { Class clazz = loadClass(sc, facesContext, handlerClass, this, null); taglibrary.putValidator(name, validatorId, clazz); } catch (NoClassDefFoundError defNotFound) { String message = defNotFound.toString(); if (message.contains("com/sun/facelets/") || message.contains("com.sun.facelets.")) { if (LOGGER.isLoggable(Level.WARNING)) { LOGGER.log(Level.WARNING, "faces.config.legacy.facelet.warning", new Object[] { handlerClass, }); } } else { throw defNotFound; } } catch (ClassNotFoundException e) { throw new ConfigurationException(e); } } else { taglibrary.putValidator(name, validatorId); } } } private void processConverter(ServletContext sc, FacesContext facesContext, NodeList converter, TagLibraryImpl taglibrary, String name) { if (converter != null && converter.getLength() > 0) { String converterId = null; String handlerClass = null; for (int i = 0, ilen = converter.getLength(); i < ilen; i++) { Node n = converter.item(i); if (n.getLocalName() != null) { switch (n.getLocalName()) { case CONVERTER_ID: converterId = getNodeText(n); break; case HANDLER_CLASS: handlerClass = getNodeText(n); break; } } } if (handlerClass != null) { try { Class clazz = loadClass(sc, facesContext, handlerClass, this, null); taglibrary.putConverter(name, converterId, clazz); } catch (NoClassDefFoundError defNotFound) { String message = defNotFound.toString(); if (message.contains("com/sun/facelets/") || message.contains("com.sun.facelets.")) { if (LOGGER.isLoggable(Level.WARNING)) { LOGGER.log(Level.WARNING, "faces.config.legacy.facelet.warning", new Object[] { handlerClass, }); } } else { throw defNotFound; } } catch (ClassNotFoundException e) { throw new ConfigurationException(e); } } else { taglibrary.putConverter(name, converterId); } } } private void processComponent(ServletContext sc, FacesContext facesContext, Element documentElement, NodeList component, TagLibraryImpl taglibrary, String name) { if (component != null && component.getLength() > 0) { String componentType = null; String rendererType = null; String handlerClass = null; Node resourceId = null; for (int i = 0, ilen = component.getLength(); i < ilen; i++) { Node n = component.item(i); if (n.getLocalName() != null) { switch (n.getLocalName()) { case COMPONENT_TYPE: componentType = getNodeText(n); break; case RENDERER_TYPE: rendererType = getNodeText(n); break; case HANDLER_CLASS: handlerClass = getNodeText(n); break; case RESOURCE_ID: resourceId = n; break; } } } if (handlerClass != null) { try { Class clazz = loadClass(sc, facesContext, handlerClass, this, null); taglibrary.putComponent(name, componentType, rendererType, clazz); } catch (NoClassDefFoundError defNotFound) { String message = defNotFound.toString(); if (message.contains("com/sun/facelets/") || message.contains("com.sun.facelets.")) { if (LOGGER.isLoggable(Level.WARNING)) { LOGGER.log(Level.WARNING, "faces.config.legacy.facelet.warning", new Object[] { handlerClass, }); } } else { throw defNotFound; } } catch (ClassNotFoundException e) { throw new ConfigurationException(e); } } else if (resourceId != null) { processResourceId(documentElement, resourceId, taglibrary, name); } else { taglibrary.putComponent(name, componentType, rendererType); } } } private void processFunctions(ServletContext sc, FacesContext facesContext, NodeList functions, TagLibraryImpl taglibrary) { if (functions != null && functions.getLength() > 0) { for (int i = 0, ilen = functions.getLength(); i < ilen; i++) { NodeList children = functions.item(i).getChildNodes(); String functionName = null; String functionClass = null; String functionSignature = null; for (int j = 0, jlen = children.getLength(); j < jlen; j++) { Node n = children.item(j); if (n.getLocalName() != null) { switch (n.getLocalName()) { case FUNCTION_NAME: functionName = getNodeText(n); break; case FUNCTION_CLASS: functionClass = getNodeText(n); break; case FUNCTION_SIGNATURE: functionSignature = getNodeText(n); break; } } } try { Class clazz = loadClass(sc, facesContext, functionClass, this, null); Method m = createMethod(clazz, functionSignature); taglibrary.putFunction(functionName, m); } catch (Exception e) { throw new ConfigurationException(e); } } } } private static Method createMethod(Class type, String signatureParam) throws Exception { // Formatted XML might cause \n\t characters - make sure we only have space characters left String signature = signatureParam.replaceAll("\\s+", " "); int pos = signature.indexOf(' '); if (pos == -1) { throw new Exception("Must Provide Return Type: " + signature); } else { int pos2 = signature.indexOf('(', pos + 1); if (pos2 == -1) { throw new Exception("Must provide a method name, followed by '(': " + signature); } else { String mn = signature.substring(pos + 1, pos2).trim(); pos = signature.indexOf(')', pos2 + 1); if (pos == -1) { throw new Exception("Must close parentheses, ')' missing: " + signature); } else { String[] ps = signature.substring(pos2 + 1, pos).trim().split(","); Class[] pc; if (ps.length == 1 && "".equals(ps[0])) { pc = new Class[0]; } else { pc = new Class[ps.length]; for (int i = 0; i < pc.length; i++) { pc[i] = ReflectionUtil.forName(ps[i].trim()); } } try { return type.getMethod(mn, pc); } catch (NoSuchMethodException e) { throw new Exception("No Function Found on type: " + type.getName() + " with signature: " + signature); } } } } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy