科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航



ZDNet>软件频道>中间件-zhiding>用JBuilder2007开发扩展JSF标签的插件

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

本文将编写一个基于JSF标签的名为"locallyDefinedBean"插件。JSF标签可以在运行时将Bean变量加到JSP-JSF而中.

来源:天极开发 2007年10月13日

关键字:插件 JSF JBuilder

本文将编写一个基于JSF标签的名为"locallyDefinedBean"插件。JSF标签可以在运行时将Bean变量加到JSP-JSF而中,在这里,我们将通过使用JSF EL(所谓JSF EL就是JSF EXPRESSION LANGUAGE)来模拟在设计时向JSP-JSF添加变量的过程。下面是具体的实现过程。

  1. 首先,使用File->New->Project->Plug-in Project来建立一个空的插件工程,这个工程使用JBuilder2007提供的默认值,并在工程名中输入myplugin。如图1所示:


图1

  2. 打开工程浏览器,切换到dependencies标签。并加入如图2所示的依赖库。


图2 dependencies标签

  3. 通过File->New->Class建立一个Java类: LocallyDeclaredBeanFactory.,并使这个类从org.eclipse.jst.jsf.context.symbol.internal.provisional.source.AbstractContextSymbolFactory继承。如图3所示。


图3

  4. 打开Java源码编辑器。你将看到两个根据抽象类自动产生的方法。然后将supports方法替换为我们自己的supports方法。代码如下:

public boolean supports(IAdaptable context)
{
 return context.getAdapter(IStructuredDocumentContext.class) != null;
}

  上面的代码表示只能调用IstructuredDocumentContext工厂。
 5. 使用如下的代码替换internalCreate中的代码

protected ISymbol internalCreate(String symbolName, int scope, IAdaptable context, List problems)
{
 //得到上下文
 final IStructuredDocumentContext sContext =(IStructuredDocumentContext)
context.getAdapter(IstructuredDocumentContext.class);
 // 为上下文建立一个DOM上下文
 final IDOMContextResolver domResolver =
IStructuredDocumentContextResolverFactory.INSTANCE.getDOMContextResolver(sContext);

 if (domResolver != null)
 {
  final Node curNode = domResolver.getNode();

  // node必须是XML属性
  if (curNode instanceof Attr)
  {
   final Attr attr = (Attr) curNode;
   final Node owningElement = attr.getOwnerElement();
   if (owningElement != null)
   {
    IProject iProject = workspaceResolver.getProject();
    if (iProject != null)
    {
     return handleSymbolCreation(symbolName, sContext, attr, owningElement, iProject);
    }
   }
  }
 }
 return null;
}

  6. 下面让我们加一个private方法来建立符号(Symbol)。

private ISymbol handleSymbolCreation(final String symbolName,
final IStructuredDocumentContext context,
final Attr attr,
final Node owningElement,
final IProject project)
{
 // 建立Tab库
 final ITaglibContextResolver resolver =IStructuredDocumentContextResolverFactory.INSTANCE
.getTaglibContextResolver(context);

 if (resolver == null || !resolver.canResolveContext(context))
 {
  return null;
 }
 final String uri = resolver.getTagURIForNodeName(owningElement);
 IBeanInstanceSymbol beanSymbol = null;
 // 处理核心标签库
 if ("http://oracle.com/tutorial/fake/taglib".equals(uri))
 {
  final String elementName = owningElement.getLocalName();
  final String attrName = attr.getName();
  if ("locallyDeclaredBean".equals(elementName))
  {
   if ("var".equals(attrName))
   {
    final NamedNodeMap attrMap = owningElement.getAttributes();
    final Node baseNameNode = attrMap.getNamedItem("classname");

    if (baseNameNode instanceof Attr)
    {
     // 得到bean的名字
     final String className = ((Attr)baseNameNode).getValue();
     // 建立一个新的空Bean实例符号
     beanSymbol = SymbolFactory.eINSTANCE.createIBeanInstanceSymbol();
     beanSymbol.setName(attr.getValue());
     try
     {
      IJavaProject javaProject = JavaCore.create(project);
      IType type = javaProject.findType(className);

      if (type != null)
      {
       IJavaTypeDescriptor2 javaTypeDescriptor = SymbolFactory.eINSTANCE.createIJavaTypeDescriptor2();
       javaTypeDescriptor.setType(type);
       beanSymbol.setJavaTypeDescriptor(javaTypeDescriptor);
      }
     }
     catch (JavaModelException jme)
     {
     }
    }
   }
  }
 }
 return beanSymbol;
}

  7. 加入注释(annotations)元数据

  我们的最终目标是加入如下的标签:

<t:locallyDeclaredBean var="x" classname="beans.MyBean"/>

  声明一个变量"x"来处理"beans.MyBean"。为了通过框架,我们必须使用无数据来注释t::locallyDeclaredBean。

  首先让我们在工程中建立一个metadata文件夹。在通过File->New->File来建立一个metadata.xml文件,如图4如示。


图4

  打开这个文件,在其中输入如下的内容。

<?xml version="1.0" encoding="UTF-8"?>
<grammar-annotation xmlns="http://org.eclipse.jsf.core/grammarAnnotationSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://org.eclipse.jsf.core/grammarAnnotationSchema D:\\EclipseWTPLatest\\WTPWorkspace\\org.eclipse.jst.jsf.core\\schema\\grammar-annotations.xsd ">
 <cm-element name="locallyDeclaredBean">
  <cm-attribute name="var">
   <property name="contributes-value-binding">
    < value>true</value>
   </property>
   <property name="value-binding-scope">
    <value>request</value>
   </property>
   <property name="value-binding-symbol-factory"> <value>tutorial.locallyDeclaredBean</value>
   </property>
  </cm-attribute>
 </cm-element>
</grammar-annotation>
8. 实现扩展

  为了声明我们的标签工厂,需要使用两个扩展点。首先我们需要扩展注释扩展点,这个扩展点用于声明我们刚才定义框架的元数据。其次,我们将注册这个工厂的ID。

  打开plugin.xml,并且选择Extensions标签,单击"Add"按钮,选择org.eclipse.jst.jsf.contentmodel.annotations.annotationFile扩展点。选择这个扩展点后,通过右键菜单New->annotationFile加入一个注释文件。并输入相应的uri和location。如图5所示。

点击放大此图片
图5

  这个扩展点可以通知这个框架当一个标签库使用uri:http://oracle.com/tutorial/fake/taglib查询元数据时查看metadata.xml文件。接下来,我们需要声明一个扩展点:org.eclipse.jst.jsf.context.symbol.contextSymbolFactory,这个扩展点声明了我们的工厂,并且给它一个唯一的ID。如图6所示。

点击放大此图片
图6

  我们要注意的是在factory属性中的值要匹配"value-binding-symbol-factory"属性的值。否则这个框架不能发现我们的工厂类。

  我们现在已经完成了标签的定义。但我们还需要构造一个动态的Web工程,以便测试我们的作品。

  为了建立一个动态的Web工程,我们首先为这个插件建立一个新的运行时工作台。我们可以通过Run->Run…来建立这个工作台。如图7所示。

点击放大此图片
图7

  一但这个工作台被装载,就可以使用New->Project->Other来建立一个Dynamic Web 工程了。

  在建立完动态Web工程后,在META-INF文件夹上通过右键菜单中的New->File新键一个叫tutorial.tld的文件。它的内容如下:

<?xml version="1.0" encoding="GB2312" ?>

<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
 <tlib-version>1.0</tlib-version>
 <jsp-version>1.2</jsp-version>
 <short-name>tutorial</short-name>
 <uri>http://oracle.com/tutorial/fake/taglib</uri>
 <tag>
  <name>locallyDeclaredBean</name>
  <tag-class>foo</tag-class>
  <tei-class>foo</tei-class>
  <body-content>empty</body-content>
  <attribute>
   <name>var</name>
   <required>true</required>
   <rtexprvalue>false</rtexprvalue>
  </attribute>
  <attribute>
   <name>classname</name>
   <required>true</required>
   <rtexprvalue>false</rtexprvalue>
  </attribute>
 </tag>
</taglib>

  最后,在src目录中建立一个叫beans.MyBean的文件,它的内容如下:

package beans;public class MyBean
{
 public String getFooProperty()
 {
  return "foo!";
 }
}
建立一个测试JSP

  现在让我们在WebContent目录中建立一个用于测试的JSP文件。然后在这个JSP文件中输入如下的内容:

<%@page contentType="text/html"%>
<%@page pageEncoding="GB2312"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@taglib uri="http://oracle.com/tutorial/fake/taglib" prefix="t" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=GB2312">
 <title>JSP 页</title>
</head>
<body>
 <f:view>
  <h1>JSP 页</h1>
  <t:locallyDeclaredBean var="x" classname="beans.MyBean"/>
  <h:outputText value="#{}"/>
 </f:view>
</body>
</html>

  现在让我们注意几点。首先,我们有一个前缀为"t"的标签库。其次,我们已经使用被定义为"x"的locallyDeclaredBean标签声明了一个Bean。这就是我们上面所描述的"beans.MyBean"。

  现在让我们测试它。将你的光标放到outputText标签的空"{}"中,然后按Ctrl-Space调用内容助手。你将看到如图8所示的界面。

点击放大此图片
图8


  你可以在Bean的属性中在x后加一个".",如图9所界面将被显示。

点击放大此图片
图9

查看本文来源

推广二维码
邮件订阅

如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

重磅专题