| <html><head> |
| <title>Implementing a New Tag-Based EL Variable Contributor for JSP</title> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <meta http-equiv="Content-Style-Type" content="text/css"> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <meta http-equiv="Content-Script-Type" content="text/javascript"> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <link rel="stylesheet" href="../../book.css" type="text/css"> |
| </head> |
| |
| <body> |
| <table summary="" cellpadding="0" cellspacing="0" width="100%"> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <tbody><tr valign="bottom"> |
| <td align="left" width="86%"> |
| <h1>Implementing a New Tag-Based EL Variable Contributor for JSP</h1> |
| </td> |
| </tr> |
| </tbody> |
| </table> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3>Summary</h3> |
| In this tutorial we will write a plugin that supplies a symbol factory |
| for a fictious JSF tag called "locallyDefinedBean" and see how it works |
| at design time. Our fictious tag adds bean variables to a JSP-JSF |
| page at runtime and we will implemented the logic necessary to simulate |
| this behaviour at design time using the JSF EL framework. Once you |
| finish this tutorial, you should have a basic grasp of what is required |
| to add tooling support for JSF-JSP tags that contribute variables to |
| JSF EL for you own real JSF tag libraries..<br> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <h3>Getting Started</h3> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| To begin, create a blank plugin project by using <span style="font-weight: bold;">File > New > Project</span>... and selecting Plug-in Project. Create the project with all of the defaults:<br> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <br> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <img alt="plugin project" src="images/new_plugin_project_dialog1.png" style="width: 500px; height: 500px;"><br> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <br> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| Next, open the plug-in dependencies for your project:<br> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <br> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <img alt="open_manifest_el" src="images/open_manifest_el.png" style="width: 263px; height: 315px;"><br> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <br> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| Add the plugin dependencies highlighted in yellow below:<br> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <br> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <img alt="dependency" src="add_dependency.png"><img alt="dependency" src="images/add_dependency.png" style="width: 1093px; height: 381px;"><br> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <p> |
| <span style="font-style: italic;"><br> |
| </span><span style="font-style: italic;"></span></p> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <p>Now we are ready to construct our factory and meta-data extensions.<br> |
| </p> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <h3>Constructing the Factory</h3> |
| The symbol factory is delegated the task of constructing your custom |
| design time variables. First, we will create the factory class.<br> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <br> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| Create a new java class in your project by clicking on the src folder and clicking <span style="font-weight: bold;">File > New > Class</span>. |
| Call the class "LocallyDeclaredBeanFactory" and make sure it extends |
| org.eclipse.jst.jsf.context.symbol.internal.provisional.source.AbstractContextSymbolFactory. |
| Also be sure enable the check box, <span style="font-weight: bold;">Inherited abstract methods</span>:<br> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <br> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <img alt="create_factory_class" src="images/create_factory_class.png" style="width: 495px; height: 599px;"><br> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <br> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| Open the new class in the Java editor. You will see two methods |
| automatically generated from the abstract parent class. For the <span style="font-style: italic;">supports</span> method, replace the method with the following:<br> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <br> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <div class="code"> |
| public boolean supports(IAdaptable context) {<br> |
| return context.getAdapter(IStructuredDocumentContext.class) != null;<br> |
| }<br> |
| </div> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <br> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| This code tells the framework to only call this factory when the context is adaptable to a structured document context.<br> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <br> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| Next, replace the internalCreate code with the following:<br> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <br> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <div class="code"> protected ISymbol internalCreate(String symbolName, int scope, IAdaptable context, List problems) <br> |
| {<br> |
| // get the contex<br> |
| final IStructuredDocumentContext sContext =<br> |
| (IStructuredDocumentContext) <br> |
| |
| context.getAdapter(IStructuredDocumentContext.class);<br> |
| <br> |
| // construct a dom resolver for this context<br> |
| final IDOMContextResolver domResolver = <br> |
| |
| IStructuredDocumentContextResolverFactory.INSTANCE.getDOMContextResolver(sContext);<br> |
| <br> |
| // if resolver can be constructed<br> |
| if (domResolver != null)<br> |
| {<br> |
| // get the current node<br> |
| // this |
| is the node marked by our meta-data as contributing an el variable<br> |
| final Node curNode = domResolver.getNode();<br> |
| <br> |
| // node must be an XML attribute<br> |
| if (curNode instanceof Attr)<br> |
| {<br> |
| final Attr attr = (Attr) curNode;<br> |
| |
| final Node owningElement = attr.getOwnerElement();<br> |
| <br> |
| |
| // attribute must have a owningElement<br> |
| if (owningElement != null)<br> |
| {<br> |
| |
| IWorkspaceContextResolver workspaceResolver =<br> |
| |
| |
| IStructuredDocumentContextResolverFactory.INSTANCE.getWorkspaceContextResolver(sContext);<br> |
| <br> |
| |
| IProject iProject = workspaceResolver.getProject();<br> |
| <br> |
| |
| if (iProject != null)<br> |
| {<br> |
| |
| return |
| handleSymbolCreation(symbolName, sContext, attr, owningElement, |
| iProject);<br> |
| }<br> |
| }<br> |
| }<br> |
| }<br> |
| <br> |
| return null;<br> |
| |
| } |
| </div> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <br> |
| |
| |
| |
| |
| |
| |
| |
| |
| You also need to add this private method that does the symbol creation:<br> |
| |
| |
| |
| |
| |
| |
| |
| |
| <br> |
| |
| |
| |
| |
| |
| |
| |
| |
| <div class="code"> |
| private ISymbol handleSymbolCreation(final String symbolName, <br> |
| final IStructuredDocumentContext context,<br> |
| final Attr attr, <br> |
| final Node owningElement,<br> |
| final IProject project)<br> |
| {<br> |
| // create tag lib resolver for this context<br> |
| final ITaglibContextResolver resolver = IStructuredDocumentContextResolverFactory.INSTANCE<br> |
| .getTaglibContextResolver(context);<br> |
| <br> |
| if (resolver == null || !resolver.canResolveContext(context)) {<br> |
| return null;<br> |
| }<br> |
| <br> |
| <br> |
| final String uri = resolver.getTagURIForNodeName(owningElement);<br> |
| IBeanInstanceSymbol beanSymbol = null;<br> |
| <br> |
| // process core taglib<br> |
| if ("http://oracle.com/tutorial/fake/taglib".equals(uri)) {<br> |
| final String elementName = owningElement.getLocalName();<br> |
| final String attrName = attr.getName();<br> |
| <br> |
| // protect ourselves by ensuring we are in the var attribute of <br> |
| // a locallyDeclaredBean<br> |
| if ("locallyDeclaredBean".equals(elementName)) {<br> |
| if ("var".equals(attrName)) {<br> |
| |
| final NamedNodeMap attrMap = |
| owningElement.getAttributes();<br> |
| |
| final Node baseNameNode = |
| attrMap.getNamedItem("classname");<br> |
| <br> |
| |
| if (baseNameNode instanceof Attr) |
| {<br> |
| |
| // get the |
| name of the bean's class<br> |
| |
| final String |
| className = ((Attr)baseNameNode).getValue();<br> |
| <br> |
| |
| // create a |
| new empty bean instance symbol<br> |
| |
| // this will |
| encapsulate all of the design time information<br> |
| |
| // about our |
| new variable<br> |
| beanSymbol = <br> |
| |
| |
| SymbolFactory.eINSTANCE.createIBeanInstanceSymbol();<br> |
| <br> |
| |
| // name the |
| new variable after the value of the var attribute<br> |
| // in the tag<br> |
| |
| |
| beanSymbol.setName(attr.getValue());<br> |
| <br> |
| |
| // next, we |
| will ask JDT to resolve the class name to a type<br> |
| try<br> |
| {<br> |
| |
| IJavaProject javaProject = JavaCore.create(project);<br> |
| |
| |
| IType type = javaProject.findType(className);<br> |
| |
| |
| <br> |
| |
| |
| // don't bother setting a type descriptor if we<br> |
| |
| |
| // can't find a type<br> |
| |
| |
| if (type != null)<br> |
| |
| |
| {<br> |
| |
| |
| // now we must create a type |
| descriptor that encapsulates <br> |
| |
| |
| // the specific type information |
| about our bean<br> |
| |
| |
| IJavaTypeDescriptor2 javaTypeDescriptor = |
| SymbolFactory.eINSTANCE.createIJavaTypeDescriptor2();<br> |
| |
| |
| javaTypeDescriptor.setType(type);<br> |
| |
| |
| beanSymbol.setJavaTypeDescriptor(javaTypeDescriptor);<br> |
| |
| |
| }<br> |
| }<br> |
| |
| catch |
| (JavaModelException jme)<br> |
| {<br> |
| |
| |
| // could not construct<br> |
| |
| |
| // fall-through<br> |
| }<br> |
| <br> |
| |
| // finally, |
| add a description that will appear in the content assis<br> |
| |
| // drop-down, |
| to prove that it really worked<br> |
| |
| |
| beanSymbol.setDetailedDescription("Hello world, this is my first tag |
| variable factory");<br> |
| }<br> |
| }<br> |
| }<br> |
| }<br> |
| <br> |
| return beanSymbol;<br> |
| |
| } |
| </div> |
| |
| |
| |
| |
| |
| |
| |
| |
| <br> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <br> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| Save the class and check that it compiles.<br> |
| |
| |
| |
| |
| |
| |
| |
| <br> |
| |
| |
| |
| |
| |
| |
| |
| <h3>Adding the Annotation Meta-data</h3> |
| |
| |
| |
| |
| |
| |
| |
| Our ultimate goal is to make a tag like this:<br> |
| |
| |
| |
| |
| |
| |
| |
| |
| <div class="code"><pre><t:locallyDeclaredBean var="x" classname="beans.MyBean"/><br></pre></div> |
| |
| |
| |
| |
| |
| <p>declare a variable called "x" to the tooling which corresponds to a bean |
| of type "beans.MyBean". In order to tell the framework this, we |
| must use meta-data to annotate the t::locallyDeclaredBean. <br> |
| </p> |
| |
| |
| |
| |
| |
| <p>First we create a new folder in our project called meta-data:<br> |
| </p> |
| |
| |
| |
| |
| |
| <p><img alt="add_meta_data_folder" src="images/add_meta_data_folder.png" style="width: 438px; height: 578px;"><br> |
| </p> |
| |
| |
| |
| |
| |
| <p>Next use right-click on the project click <span style="font-weight: bold;">File > New > File</span> to create a new meta-data xml file:<br> |
| </p> |
| |
| |
| |
| |
| |
| <p><img alt="add_metadata_file" src="images/add_metadata_file.png" style="width: 438px; height: 578px;"><br> |
| </p> |
| |
| |
| |
| |
| |
| <p>Open the file as source and copy the following markup into the editor:<br> |
| </p> |
| |
| |
| |
| |
| |
| <pre><?xml version="1.0" encoding="UTF-8"?><br><grammar-annotation <br> xmlns="http://org.eclipse.jsf.core/grammarAnnotationSchema"<br> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br> xsi:schemaLocation="http://org.eclipse.jsf.core/grammarAnnotationSchema D:\\EclipseWTPLatest\\WTPWorkspace\\org.eclipse.jst.jsf.core\\schema\\grammar-annotations.xsd "><br> <cm-element name="locallyDeclaredBean"><br> <cm-attribute name="var"><br> <property name="contributes-value-binding"><br> <value>true</value><br> </property><br> <property name="value-binding-scope"><br> <value>request</value><br> </property><br> <property name="value-binding-symbol-factory"><br> <value>tutorial.locallyDeclaredBean</value><br> </property><br> </cm-attribute><br> </cm-element><br></grammar-annotation><br><br></pre> |
| |
| |
| |
| |
| |
| The important things to note are "cm-element" and "cm-attribute" that |
| declare to the meta-data framework that attribute "var" on element |
| "locallyDeclaredBean" is what is of interest. The property |
| "value-binding-symbol-factory" is what points the framework to our |
| factory. However the value here is not the factory itself, but an |
| id for its extension, which we'll define in the next section.<br> |
| |
| |
| |
| |
| |
| <br> |
| |
| |
| |
| |
| |
| <h3>Implementing the extensions</h3> |
| |
| |
| |
| |
| |
| Two extension point work together to declare our symbol factory. |
| First we will extend the annotations extension point to declare |
| the meta-data that we just defined to the framework. Second, we will |
| register the factory id.<br> |
| |
| |
| |
| |
| |
| <br> |
| |
| |
| |
| |
| |
| Open the plugin.xml editor for the project and select the <span style="font-weight: bold;">Extensions </span>tab, click <span style="font-weight: bold;">Add...</span> and select <span style="font-weight: bold;">org.eclipse.jst.jsf.contentmodel.annotations.annotationFile</span>. Right click on the new extension element in the tree on the left and add a new <span style="font-weight: bold;">annotationFile</span> entry. Enter the uri and location information as shown.<br> |
| |
| |
| |
| |
| |
| <br> |
| |
| |
| |
| |
| |
| <img alt="annotation ext point" src="images/add_annotation.png" style="width: 825px; height: 710px;"><br> |
| |
| |
| |
| |
| |
| <br> |
| |
| |
| |
| |
| |
| Adding this extension point tells the framework to look in our |
| tutorial-metadata.xml file when queried for metadata about a tag |
| library with the identifying uri |
| http://oracle.com/tutorial/fake/taglib. Note the strange name of |
| the uri in this case. That is to emphasize that they tag library |
| we are creating a tag variable for doesn't really exist -- it's just |
| for this tutorial.<br> |
| |
| |
| |
| |
| |
| <br> |
| |
| |
| |
| |
| |
| Next, we need to declare an extension to <span style="font-weight: bold;">org.eclipse.jst.jsf.context.symbol.contextSymbolFactory</span> that declares our factory and gives it a unique id:<br> |
| |
| |
| |
| |
| |
| <br> |
| |
| |
| |
| |
| |
| <img alt="add symbol factory" src="images/add_symbol_factory.png" style="width: 827px; height: 708px;"><br> |
| |
| |
| |
| |
| |
| <br> |
| |
| |
| |
| |
| |
| Notice that the value we put in the <span style="font-weight: bold;">factory</span> |
| property matches what is in the "value-binding-symbol-factory" metadata |
| property. These values must match so that the framework can find |
| our factory.<br> |
| |
| |
| |
| |
| |
| <br> |
| |
| |
| |
| |
| |
| We are now finished with defining our tag contributor (easy |
| huh?). But we're not quite finished. We need to construct a |
| dynamic web project complete with our fake tag library to test out what |
| we've done.<br> |
| |
| |
| |
| |
| |
| <br> |
| |
| |
| |
| |
| |
| <h3>Setting Up the Dynamic Web Project</h3> |
| |
| |
| |
| |
| |
| First we need to launch a new runtime workbench with our plugin installed. To do this, execute <span style="font-weight: bold;">Run > Run...</span> to create a new launch profile. Create a new Eclipse Application and launch it with the defaults:<br> |
| |
| |
| |
| |
| |
| <br> |
| |
| |
| |
| |
| |
| <img alt="run workbench" src="images/run_workbench.png" style="width: 800px; height: 640px;"> <br> |
| |
| |
| |
| |
| |
| <br> |
| |
| |
| |
| |
| |
| Once the workbench has loaded, go to <span style="font-weight: bold;">New > Project > Other</span> and select <span style="font-weight: bold;">Web > Dynamic Web Project</span> and hit <span style="font-weight: bold;">Next</span>.<br> |
| |
| |
| |
| |
| |
| <br> |
| |
| |
| |
| |
| |
| Name the project and hit next. From the <span style="font-weight: bold;">Project Facets</span> wizard page, enable the <span style="font-weight: bold;">JavaServer Faces </span>facet and click <span style="font-weight: bold;">Next</span>. Click <span style="font-weight: bold;">Next</span> at the <span style="font-weight: bold;">Web Modules </span> page leaving the defaults unchanged. Last you will come to the <span style="font-weight: bold;">JSF Capabilities</span> |
| page. Here you need to set up your JSF Libraries (see user's |
| guide for more details on JSF Libraries). When you are done, |
| click <span style="font-weight: bold;">Finish</span>. This should create a skeletal JSF project. Next we will add the "fake" tag library.<br> |
| |
| |
| |
| |
| <br> |
| |
| |
| |
| |
| <h3>Adding the demonstration tag library</h3> |
| |
| |
| |
| |
| Right-click on the META-INF folder under the WebContent folder in your new Dynamic Web Project and select <span style="font-weight: bold;">New > File</span> and name the file tutorial.tld and save the following into it:<br> |
| |
| |
| |
| |
| <br> |
| |
| |
| |
| |
| <pre><?xml version="1.0" encoding="ISO-8859-1" ?><br><br><!DOCTYPE taglib<br> PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"<br> "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"><br><br><br><taglib><br><br><br> <!-- ========== Tag Library Description Elements ========================= --><br><br><br> <tlib-version>1.0</tlib-version><br> <jsp-version>1.2</jsp-version><br> <short-name>tutorial</short-name><br> <uri>http://oracle.com/tutorial/fake/taglib</uri><br> <description><br> An tld to help demonstrate how to implemented tag contributed EL variables.<br> NOTE: this is a taglib for demonstration purposes: it is not fully or correctly<br> implemented and it is not intended to be run in real JSP applications<br> </description><br> <tag><br><br> <name>locallyDeclaredBean</name><br> <tag-class>foo</tag-class><br> <tei-class>foo</tei-class><br> <body-content>empty</body-content><br> <description><br> Tag declares a new bean variable at request scope based on the name <br> and classname provided.<br> </description><br><br> <attribute><br> <name>var</name><br> <required>true</required><br> <rtexprvalue>false</rtexprvalue><br> <description><br> The name of the locally declared variable. This name will be added<br> to the EL variable namespace for the JSP in which it is used at request scope<br> </description><br> </attribute><br><br> <attribute><br> <name>classname</name><br> <required>true</required><br> <rtexprvalue>false</rtexprvalue><br> <description><br> The fully qualified name of the Java class that will be instantiated as<br> the backing bean for the locally declared bean.<br> </description><br> </attribute><br> </tag><br> <br></taglib><br><br></pre> |
| |
| |
| |
| and save and close the file.<br> |
| |
| |
| <br> |
| |
| |
| Create a simple bean called <span style="font-weight: bold;">beans.MyBean</span> in the src folder and paste in the following code:<br> |
| |
| |
| |
| <div class="code"><pre>package beans;<br><br>public class MyBean <br>{<br> public String getFooProperty()<br> {<br> return "foo!";<br> }<br>}<br></pre></div> |
| |
| |
| <br> |
| |
| |
| <h3>Create the Test JSP<br> |
| </h3> |
| |
| |
| |
| Now we will create a test JSP file by right-clicking on the <span style="font-weight: bold;">WebContent</span> folder and clicking <span style="font-weight: bold;">New > Other</span> and in the tree selecting <span style="font-weight: bold;">Web > JSP</span>. Select the defaults and click finish. Then, open the file and replace the contents with the following:<br> |
| |
| |
| |
| <br> |
| |
| |
| |
| <pre><%@page contentType="text/html"%><br><%@page pageEncoding="UTF-8"%><br><%--<br>The taglib directive below imports the JSTL library. If you uncomment it,<br>you must also add the JSTL library to the project. The Add Library... action<br>on Libraries node in Projects view can be used to add the JSTL 1.1 library.<br>--%><br><br><%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <br><%@taglib uri="http://java.sun.com/jsf/core" prefix="f"%><br><%@taglib uri="http://java.sun.com/jsf/html" prefix="h"%><br><%@taglib uri="http://oracle.com/tutorial/fake/taglib" prefix="t" %><br><br><br><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"<br> "http://www.w3.org/TR/html4/loose.dtd"><br><br><html><br> <head><br> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><br> <title>JSP Page</title><br> </head><br> <body><br> <f:view><br> <h1>JSP Page</h1><br> <!-- no errors --><br> <t:locallyDeclaredBean var="x" classname="beans.MyBean"/><br> <h:outputText value="#{}"/><br> </f:view><br> </body><br></html><br><br></pre> |
| |
| |
| |
| Note a few things. First, we have a taglib declared for our "fake" |
| tag library with prefix "t". Second, we have declared a bean |
| using the locallyDeclaredBean tag to declare a variable "x" of the type "beans.MyBean" that we created above.<br> |
| |
| <br> |
| |
| So now let's test it. Position your cursor inside the empty "{}" |
| braces in the value attribute of the outputText tag. Type |
| Ctrl-Space to request content assist. You should see your bean |
| "x" in the list:<br> |
| |
| <br> |
| |
| <img alt="content assist" src="images/content_assist_1.png" style="width: 938px; height: 277px;"><br> |
| |
| |
| |
| |
| |
| |
| |
| <br> |
| |
| You can try requesting content assist for the property we added in the bean by typing a period after the "x":<br> |
| |
| <br> |
| |
| <img alt="content assist 2" src="images/content_assist_2.png" style="width: 623px; height: 194px;"><br> |
| |
| <br> |
| |
| Select the property so that the EL text reads "x.fooProperty". Finally, right-click on the JSP file in the <span style="font-weight: bold;">File Explorer</span> and select <span style="font-weight: bold;">Validate</span> to prove that your variable and property are recognized correctly by the validation framework.<br> |
| <br> |
| <h3>Conclusion</h3> |
| We hope this tutorial has helped you understand how to use the JSF |
| tooling to add design time support for your JSF component tag libraries |
| that contribute EL variables. If you need further help or have |
| trouble with this tutorial please post to our web forum on |
| eclipse.org. Putting "EL Variable Contributor" in the subject |
| will ensure speedier response from knowledgeable parties.<br> |
| </body></html> |