top
Loading...
用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所示:


圖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

作者:http://www.zhujiangroad.com
來源:http://www.zhujiangroad.com
北斗有巢氏 有巢氏北斗