级别: 初级 Lakshmi Priya, 软件工程师, IBM
2009 年 10 月 26 日 Java portlet 规格 2.0 中引入的新特性,基于 JSR 286,支持 portlets 之间的协作。事件和公共赋值变量是 portlets 相互之间可以交流的两个机理。在对一些关键概念做简短介绍之后,本文向您介绍如何使用 IBM® Rational® Application Developer V7.5 中的 Portal Toolkit,来创建一个 JSR 286 基本 portlet 的范例。在这个过程中,它解释了 Portal Toolkit 是怎样加速整个过程以升级这些功能的。详细的信息向您展示了,通过使用新事件向导和改进的 portlet 部署描述可视化编辑器来使用事件和公共赋值参数。您在本文中开发的范例程序,可以部署到 IBM® WebSphere® Portal V6.1 上。
关键概念
本文首先介绍一下关键概念,然后使用范例 portlet 程序来展示一下这些概念。
事件
Java™Specification Request(JSR)286 规格的 2 版本,使 portlets 发送和接受事件成为可能。事件能使 portlets 相互之间进行交流。IBM® Rational® Application Developer V7.5 提供了一系列的工具,以定义事件,激活 portlets,并使用事件在它们之间传递数据。一个 portlet 可以处理交流的双方:
- 向其他 portlets 发送事件
- 从其他 portlets 那里接受和处理事件
事件的属性
每一个事件必须有一个名字,可能还要有其他属性:
-
Name:事件独一无二的名字。该事件名必须是一个完整的 QName,跟在 XML 规格中定义的名字一样,它由一个名字区(例如,http://www.ibm.com)和本地区(例如,sampleEvent)组成。您可以为多个事件使用相同的名字区,只需将其宣布为默认的名字区,然后为每一个事件只指定本地区。
-
Description:(可选项)对事件所做的描述。
-
Value type:(可选项)随事件一起传递的值的 Jazz 类名。
-
Alias:(可选项)事件名字区特定的名字。
按照如下步骤,创建一个 portlet 程序,该程序集成了事件和公共赋值变量,以便在 portlets 之间进行交流:
- 创建一个 JSR 286 portlet 项目和 portlets。
- 在 portlet 部署描述器(PDD)中创建一个事件定义。
- 添加事件作为 portlet 支持的发布或者处理的事件。
- 编辑 portlet 类中的过程行为或者事件代码,以发布或者处理事件。
- 添加公共赋值变量。
- 向服务器发布 portlet 项目。
- 将 portlets 集中到一起。
通过使用 Rational Application Developer V7.5 提供的工具,可以极大地简化这些任务。
公共赋值变量
JSR 286 规格提供了支持 portlet 之间协作的另外一个机理:公共赋值变量(查看资源以找到更多关于它的信息)。这些参数为在 portlet 之间共享请求参数提供了一种途径。
公共赋值变量的属性
每一个变量必须要有一个名字,或者可能还要有其他的属性:
-
Name:(必需的)参数独一无二的名字,要么是一个字符串要么是名字空间特定的名字。选择默认的名字空间或者指定一个不同的。您所输入的作为事件名的本地字符串会添加到名字空间。
-
Identifier:(必需的) portlet 代码中使用的字符串以引用赋值变量。
-
Description:(可选的)对赋值变量的描述。
-
Alias:(可选的)对参数的名字空间区域内的名字。
本文中使用的范例程序
在本文中,范例的 portlet 程序展示了 JSR 286 的事件和公共赋值变量的实用性。传递公司使用的范例程序,以维持它的顺序和客户。它由三个 portlets 组成:
- Orders portlet 维持了公司顺序每月的细节信息。
- OrderDetails portlet 显示了某个顺序的细节信息。
- TrackingDetails portlet 显示了某个顺序的追踪细节信息。
文章描述了怎样创建事件和公共赋值变量,以及怎样在例子中使用它们。查看 Download 以得到完整的范例程序。
范例的用例
用户可以选择一个月的顺序 ID,以查看它的顺序和追踪细节信息。这是通过使用事件和公共赋值变量得以实现的。 Orders portlet 总结了一个月内所有顺序的信息。当用户点击 Orders portlet 中顺序的 ID 时,portlet 就会激发一次事件。该事件会由显示被选中顺序 ID 细节信息的 OrderDetails portlet 处理的。然后 OrderDetails portlet 会从顺序细节信息那里获取顺序的追踪 ID,并将细节信息作为赋值变量传递给 TrackingDetails portlet 。最后 TrackingDetails portlet 会显示出该顺序的追踪细节信息。
- 为了让该用例运转,使用 Rational Application Developer 7.5 中的 Portal Toolkit,来声明一个名为
OrderIDType 的事件。该事件对于 Orders portlet 是作为支持的公布事件而添加,对于 OrderDetails portlet 是作为支持的处理事件而添加。
- 您可以创建
TrackingIDType 公共赋值变量,并使 OrderDetails 和 TrackingDetails portlets 支持该参数。
创建 JSR 286 portlet 项目和 portlets
Rational Application Developer 中的 Portlet Project 向导,支持对 JSR 286-compliant portlet 项目的创建。
按照以下步骤创建 portlet 项目:
- 点击 File > New > Portlet Project 以打开向导。
- 指定细节信息,如图 1 所示:
- 对于目标运行时环境,选择 WebSphere Portal v6.1。
- 对于 portlet API,选择 JSR 286 Portlet。
- 对于 portlet 类型,选择 Basic Portlet.
图 1. JSR 286 portlet 项目创建向导
接下来的一步,是向您创建的 portlet 程序添加需要的 portlets 。既然文章在范例程序中涉及到了三个 portlets,那么您就可以向 portlet 项目添加这些 portlets (见于图 2 ):
- 右击 portlet 部署描述器并选择 New > Portlet。
- 输入 portlet 名为
OrderDetail,然后点击 Finish。
- 重复以上的步骤,以添加其他两个 portlets:OrdersPortlet 和 TrackingPortlet。
图 2. Portlet 创建向导
注意:
本文并没有讨论怎样编辑 Java™Server Pages(JSP™)文件,并添加您想对 portlets 所要的功能,因为现在的重点是创建事件和公共赋值变量。我们的假设是 portlets 得到变动时, Orders portlet 会显示该月的顺序,OrderDetail portlet 会显示顺序的细节信息,而 Tracking portlet 会显示顺序的追踪细节信息。
图 3 显示了当 OrdersPortlet 发布在 WebSphere Application Server V6.1 上时是什么样子的。
图 3. Orders Portlet
在 portlet 部署描述器中创建一个事件定义
使用 Rational Application Developer 中包含的事件向导创建事件会十分容易 。按照以下方法创建三个事件:
- 在 Project Explorer 中展开 portlet 项目。
- 右击 portlet 部署编辑器并选择 Event。
如图 4 所示,在 Event 下有两个可用的选项:
- 对 Publish Event 激活该 Portlet
- 对 Process Event 激活该 Portlet
图 4. 事件选项
点击以放大
添加事件作为 portlet 公布事件
当您选择第一个选项时会执行这些操作,该选项就是“对 Publish Event 激活该 Portlet”。
- 向 portlet 程序添加事件定义
- 添加事件作为 portlet 支持的公布事件
- 编辑
processAction() 或者 processEvent() 方法以公布事件
当您选择其他的选项,也就是“对 Process Event 激活该 Portlet”时,执行以下的操作:
- 如果该事件定义尚未存在,那么就向 portlet 程序添加事件定义
- 向 portlet 添加作为支持处理的事件
- 编辑 processEvent() 方法以处理事件
接下来的一步是使用向导来创建事件。按照以下方法,激活 Orders portlet 以公布 OrderIDType 事件:
- 右击 portlet 部署描述器下面的 Ordersportlet 。
- 选择 Event > Enable this Portlet to Publish events。该操作将会打开向导。
- 指定细节信息,如图 5 所示:
- 对于 Event 名字,选择 OrderIDType。
- 对于 Value 类型,指定 String。
图 5. 激活 portlet 以公布事件的向导
- 点击 Finish。
该向导将会对 portlet 部署描述器做出以下两个更改:
- 向 portlet 程序添加事件定义
- 添加事件作为 portlet 支持的公布事件
列表 1 所示的代码,显示了事件向导是怎样编辑 portlet 部署描述器代码的。
列表 1. 部署描述器代码更改
<?xml version="1.0" encoding="UTF-8"?>
<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
version="2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd
http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
id="com.ibm.jsr286eventrenderparam.JSR286EventRenderParamPortlet.19a07d46c1">
<portlet>
<portlet-name>OrderDetail</portlet-name>
<?xml version="1.0" encoding="UTF-8"?>
<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
version="2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd
http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
id="com.ibm.jsr286eventrenderparam.JSR286EventRenderParamPortlet.19a07d46c1">
<portlet>
<portlet-name>OrderDetail</portlet-name>
<display-name xml:lang="en">OrderDetail</display-name>
<display-name>OrderDetail</display-name>
<portlet-class>
com.ibm.jsr286eventrenderparam.OrderDetailPortlet
</portlet-class>
<init-param>
<name>wps.markup</name>
<value>html</value>
</init-param>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
</supports>
<supported-locale>en</supported-locale>
<resource-bundle>
com.ibm.jsr286eventrenderparam.nl.OrderDetailPortletResoure
</resource-bundle>
<portlet-info>
<title>OrderDetail</title>
<short-title>OrderDetail</short-title>
<keywords>OrderDetail</keywords>
</portlet-info>
</portlet>
<portlet>
<portlet-name>OrdersPortlet</portlet-name>
<display-name xml:lang="en">OrdersPortlet</display-name>
<display-name>OrdersPortlet</display-name>
<portlet-class>
com.ibm.jsr286eventrenderparam.OrdersPortlet
</portlet-class>
<init-param>
<name>wps.markup</name>
<value>html</value>
</init-param>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
</supports>
<supported-locale>en</supported-locale>
<resource-bundle>
com.ibm.jsr286eventrenderparam.nl.OrdersPortletResource
</resource-bundle>
<portlet-info>
<title>OrdersPortlet</title>
<short-title>OrdersPortlet</short-title>
<keywords>OrdersPortlet</keywords>
</portlet-info>
<supported-publishing-event>
<name>OrderIDType</name>
</supported-publishing-event>
</portlet>
<portlet>
<portlet-name>TrackingPortlet</portlet-name>
<display-name xml:lang="en">TrackingPortlet</display-name>
<display-name>TrackingPortlet</display-name>
<portlet-class>
com.ibm.jsr286eventrenderparam.TrackingPortlet
</portlet-class>
<init-param>
<name>wps.markup</name>
<value>html</value>
</init-param>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
</supports>
<supported-locale>en</supported-locale>
<resource-bundle>
com.ibm.jsr286eventrenderparam.nl.TrackingPortletResource
</resource-bundle>
<portlet-info>
<title>TrackingPortlet</title>
<short-title>TrackingPortlet</short-title>
<keywords>TrackingPortlet</keywords>
</portlet-info>
</portlet>
<default-namespace>http://JSR286EventRenderParam/</default-namespace>
<event-definition>
<name>OrderIDType</name>
<value-type>java.lang.String</value-type>
</event-definition>
</portlet-app>
|

 |

|
编辑 portlet 类的过程操作代码,以发布事件
processAction()方法会得到编辑以发布事件,如列表 2 所示。
列表 2. 对 processAction()事件所做的编辑
public void processAction(ActionRequest request, ActionResponse response)
throws PortletException, java.io.IOException {
if( request.getParameter(FORM_SUBMIT) != null ) {
// Set form text in the session bean
OrdersPortletSessionBean sessionBean = getSessionBean(request);
if( sessionBean != null )
sessionBean.setFormText(request.getParameter(FORM_TEXT));
}
//Initialize the fields in the class as per your requirement
java.lang.String sampleObject = new java.lang.String();
response.setEvent("OrderIDType", sampleObject);
}
|
您必须编辑事件向导生成的代码,以满足您的需求。因为 OrderIDType 需要被发送出去,所以在选中顺序 ID 时,操作请求会产生顺序 ID(见于列表 3)。
列表 3. 发送 OrderIDType 的代码
String order_id = request.getParameter(ORDER_ID);
if (order_id!=null)
response.setEvent("OrderIDType", order_id);
|
向导会编辑 portlet 部署描述器下面的 portlet,如图 6 中的 Project Explorer 所示。在 OrdersPortlet 节点下,会出现 OrderIDType 事件。
图 6. Project Explorer
添加 portlet 支持的处理事件
接下来,OrderDetail portlet 需要接受顺序 ID。换句话说,OrderDetail portlet 现在需要处理发布的事件了。
按照以下步骤,激活 portlet 以处理事件:
- 展开 Portlet Deployment Descriptor 节点。
- 右击 OrderDetailPortlet 并选择 Event > Enable this Portlet to Process Event。
图 7. 过程事件选项
点击以放大
“Enable this portlet to process events”向导会打开,如图 8 所示。
图 8. 对 Process 事件窗口激活 Portlet
- 对于 Event Name,选择 OrderIDType,它已经使用事件发布向导得到声明了。您不能在这里编辑事件定义,但是您可以在 portlet 部署描述器中手动编辑它。
- 点击 Finish 以完成这个过程:
- 为 OrderDetail Portlet 添加
supported-processing-event 元素(当您发布该事件时您已经添加了事件定义)。
- 编辑
processEvent() 方法以处理事件
OrderDetail portlet 的 portlet 部分如列表 4 所示得到编辑。
列表 4. 对 OrderDetail portlet 所做的更改
<portlet>
<portlet-name>OrderDetail</portlet-name>
<display-name xml:lang="en">OrderDetail</display-name>
<display-name>OrderDetail</display-name>
<portlet-class>
com.ibm.jsr286eventrenderparam.OrderDetailPortlet
</portlet-class>
<init-param>
<name>wps.markup</name>
<value>html</value>
</init-param>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
</supports>
<supported-locale>en</supported-locale>
<resource-bundle>
com.ibm.jsr286eventrenderparam.nl.OrderDetailPortletResoure
</resource-bundle>
<portlet-info>
<title>OrderDetail</title>
<short-title>OrderDetail</short-title>
<keywords>OrderDetail</keywords>
</portlet-info>
<supported-processing-event>
<name>OrderIDType</name>
</supported-processing-event>
</portlet>
|
在 portlet 类中编辑事件代码以处理事件
如列表 5 所示,processEvent()方法也得到了更改,该方法对处理接受的事件负责。
列表 5. 对 processEvent( ) 方法所做的更改
public void processEvent(EventRequest request, EventResponse response)
throws PortletException, java.io.IOException {
Event sampleEvent = request.getEvent();
if(sampleEvent.getName().toString().equals("OrderIDType")) {
Object sampleProcessObject = sampleEvent.getValue();
}
|
您需要从 OrderDetail portlet 向 Tracking portlet 发送 TrackingID。因此,您需要编辑 processEvent() 方法,如列表 6 中的粗体代码所示。
列表 6. 对 processEvent( ) 方法所做的更改
public void processEvent(EventRequest request, EventResponse response)
throws IOException, PortletException {
Event sampleEvent = request.getEvent();
if(sampleEvent .getName().equals("OrderIDType")) {
Object sampleProcessObject = sampleEvent.getValue();
response.setRenderParameter(ORDER_ID, sampleProcessObject.toString());
//set the order id as a render parameter
OrderDetail od = ShippingDB.getOrderDetail(ev.getValue().toString());
if (od != null) {
request.getPortletSession().setAttribute(ORDER_DETAIL, od);
response.setRenderParameter("TrackingID", od.getTrackingId());
//fetch the tracking id from the order details, and set it as a
render parameter.
}
}
}
|
为了让 OrderDetails Portlet 显示 Order Details,您就需要编辑 doView() 方法以添加如列表 7 所示的粗体代码。
列表 7. 对 doView( ) 方法所做的编辑
String orderId = (String) request.getParameter(ORDER_ID);//get the order set
in the processAction()
OrderDetail od = ShippingDB.getOrderDetail(orderId);
PortletURL actionURL = ShippingUtils.createSimpleActionURL(ORDER_DETAILS, response);
odb.setActionURL(actionURL);
if (od != null)
odb.setOrderDetail(od);
getPortletContext().getRequestDispatcher(getJspFilePath(request, VIEW_JSP))
.include(request, response);
|
添加公共赋值变量
接下来的一步,就是使用公共赋值变量机理来共享 OrderDetail portlet 和 Tracking portlet 之间的追踪 ID。
- 为 EventSample 项目打开 portlet 部署描述器。
- 选择 Render Params 项,然后点击 Add 以创建带有默认名(NewPublicRenderParam)的公共赋值变量。
- 将 Name 和 Identifier 区域更改为
TrackingID,如图 9 所示。
图 9. Portlet Deployment Descriptor 编辑器中的 Render Params 项
点击以放大
该操作将会添加如列表 8 所示的部分,到 portlet 部署描述器中的 portlet 程序定义中。
列表 8. 添加至 portlet 部署描述器中的代码片段
<public-render-parameter>
<identifier>TrackingID</identifier>
<name>TrackingID</name>
</public-render-parameter>
|
- 因为该参数需要由 Tracking 和 OrderDetail portlets 共享,所以您需要添加一个参数,作为每一个 portlets 都支持的公共赋值参数。
- 从 Portlets 项中,选择 TrackingPortlet。
- 切换至右边窗格中的公共赋值变量,并点击 Select。
- 对于名字,选择 Tracking ID,它是在编辑器中的 Render Params 项中创建的,如图 10 所示。
- 点击 OK。
- 重复第 4 步和第 5 步,以添加
TrackingID 作为 OrdersPortlet 的公共赋值变量。
图 10 显示了添加给 portlets 的公共赋值变量。
图 10. 添加的公共赋值变量
点击以放大
对 portlet 部署描述器做如列表 9 所示的更改。
列表 9. 对 portlet 部署描述器所做的更改
<portlet>
<portlet-name>OrdersPortlet</portlet-name>
<display-name xml:lang="en">OrdersPortlet</display-name>
<display-name>OrdersPortlet</display-name>
<portlet-class>
com.ibm.jsr286eventrenderparam.OrdersPortlet
</portlet-class>
<init-param>
<name>wps.markup</name>
<value>html</value>
</init-param>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
</supports>
<supported-locale>en</supported-locale>
<resource-bundle>
com.ibm.jsr286eventrenderparam.nl.OrdersPortletResource
</resource-bundle>
<portlet-info>
<title>OrdersPortlet</title>
<short-title>OrdersPortlet</short-title>
<keywords>OrdersPortlet</keywords>
</portlet-info>
<supported-publishing-event>
<name>OrderIDType</name>
</supported-publishing-event>
<supported-public-render-parameter>
TrackingID
</supported-public-render-parameter>
</portlet>
<portlet>
<portlet-name>TrackingPortlet</portlet-name>
<display-name xml:lang="en">TrackingPortlet</display-name>
<display-name>TrackingPortlet</display-name>
<portlet-class>
com.ibm.jsr286eventrenderparam.TrackingPortlet
</portlet-class>
<init-param>
<name>wps.markup</name>
<value>html</value>
</init-param>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
</supports>
<supported-locale>en</supported-locale>
<resource-bundle>
com.ibm.jsr286eventrenderparam.nl.TrackingPortletResource
</resource-bundle>
<portlet-info>
<title>TrackingPortlet</title>
<short-title>TrackingPortlet</short-title>
<keywords>TrackingPortlet</keywords>
</portlet-info>
<supported-public-render-parameter>TrackingID
</supported-public-render-parameter>
</portlet>
|
- 您必须编辑 Tracking portlet 的
doView() 方法,以显示追踪 的细节信息,它建立在顺序的 TrackingID 的基础之上(见于列表 10 )。
列表 10. 对 doView( ) 方法所做的更改
String renderParam = request.getParameter("TrackingID");
//fetch the tracking id render param which was set in the OrderDetails Portlet
TrackingDetailBean tdb = new TrackingDetailBean();
request.setAttribute(TRACKING_DETAIL_BEAN, tdb);
if (renderParam!=null && renderParam.length()>0) {
PortletURL actionURL =
ShippingUtils.createSimpleActionURL(TRACKING_DETAILS, response);
tdb.setActionURL(actionURL);
PortletURL rdActionURL =
ShippingUtils.createSimpleActionURL(ROUTING_DETAILS, response);
tdb.setRoutingDetailActionURL(rdActionURL);
TrackingDetail td = ShippingDB.getTrackingDetail(renderParam);
if (td != null) {
tdb.setTrackingDetail(td);
getPortletContext().getRequestDispatcher(getJspFilePath
(request, VIEW_JSP)).include(request, response);
} else {
//Tracking id not found; print error page
tdb.setErrorMessage("Tracking Id " + renderParam + " not found.");
getPortletContext().getRequestDispatcher(getJspFilePath
(request, ERROR_JSP)).include(request, response);
}
}
|
公布 portlet 项目
现在您就可以在 WebSphere Application Server V6.1 上发布 portlet 程序了:
- 右击 portlet 项目(见于图 11 )并选择 Run As > Run on Server。
图 11. 发布 portlet 项目
点击以放大
- 选择 WebSphere Portal V6.1 Server,如图 12 所示。
- 点击 Next,然后点击 Finish。
图 12. 选择您想要运行 portlet 程序的服务器
将 portlets 集中起来
入口服务器可用的布线工具,可以帮助您集中 portlets 之间的关系。
按照以下方式,访问布线工具:
- 为 portlets 所在的页面选择 Edit Page Layout。
- 选择 Wires 项。
- 对源 portlet,从下拉菜单中选择 OrdersPortle,对于目标 portlet,选择 OrderDetail Portlet(图 13)。对于事件名,为 Sending 和 Receiving 区域右击下拉箭头。
图 13. 在 portlet 程序中添加线以定义关系
点击以放大
- 点击加号然后点击 Done。
- 选择一个顺序 ID(例如, OrdersPortlet 中的第一个顺序)。
当您点击顺序 ID 时,会由 Orders portlet 激发一次事件,它将会向 Order Details portlet 发送 Order_ID 值。当该 portlet 接受顺序 ID 时,Order Details Portlet 会处理事件。它获取了顺序 ID 的细节信息并为用户显示出这些信息。另外,Order Details portlet 会获取顺序的追踪 ID,并交流 ID 以追踪细节部分的 portlet,因为 TrackingID 已经为 Order Details 和 Tracking portlets 作为共享的赋值参数而得到添加。因为,一旦用户点击顺序 ID,那么顺序的细节信息和追踪的细节信息就会显示给用户了(见于图 14)。
图 14. Orders portlet
现在用户可以看到顺序和追踪的细节信息,如图 15 所示。因为,事件和公共赋值变量用于向各自的 portlets 传递 OrderID 和 TrackingID。
图 15. Order 和 Tracking 细节的 portlets
点击以放大
正如您在这里看到的那样, Rational Application Developer 7.5 提供的工具,极大地简化了事件和公共赋值变量的创建。您只需编辑生成的代码,以满足程序的需要。
下载 | 描述 | 名字 | 大小 | 下载方法 |
|---|
| 如何创建事件和公共赋值参数 | JSR286EventRenderParam.zip | 63KB | HTTP |
|---|
参考资料 学习
获得产品和技术
关于作者  | 
|  | Lakshmi Priya 是一名软件开发人员,在位于印度 Delhi 的 IBM 印度软件实验室,主要从事 Rational Application Developer 中的门户工具组件的工作。她负责领导 Portlet Tooling 子组件团队。她开始在班加罗尔的一个泛计算团队工作,并且一直从事 portlet 和基于 Eclipse 技术的工作。 |
对本文的评价
|