服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

用jbuilder2007开发扩展jsf标签的插件


  本文将编写一个基于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所示:

用jbuilder2007开发扩展jsf标签的插件(图一)
图1

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

用jbuilder2007开发扩展jsf标签的插件(图二)
图2 dependencies标签

  3. 通过file->new->class建立一个java类: locallydeclaredbeanfactory.,并使这个类从org.eclipse.jst.jsf.context.symbol.internal.provisional.source.abstractcontextsymbolfactory继承。如图3所示。

用jbuilder2007开发扩展jsf标签的插件(图三)
图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如示。

用jbuilder2007开发扩展jsf标签的插件(图四)
图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所示。

用jbuilder2007开发扩展jsf标签的插件(图五)
图5

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

用jbuilder2007开发扩展jsf标签的插件(图六)
图6

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

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

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

用jbuilder2007开发扩展jsf标签的插件(图七)
图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所示的界面。

用jbuilder2007开发扩展jsf标签的插件(图八)
图8


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

用jbuilder2007开发扩展jsf标签的插件(图九)
图9

扫描关注微信公众号