...
提供了几种类型的 FilterOperation。筛选器操作通过调用 excecute 方法执行,该方法使用两个自变量:来自 HTTP 响应 HTML 的文本的下一行文本,以及包含名称/值对的映射,这些名称/值对可用来替换找到的令牌。在执行该操作的过程中,可能会向令牌“映射”里添加新的值或删除一些值,文本行也可能在传递到树中的下一操作之前被更改。令牌是通过以“@”字符包围令牌值名称来定界的,如 @TOKEN@。令牌可用于各种筛选器操作值,也可以用作存储处理响应 HTML 时收集的数据的变量;例如,可创建一个令牌来存储有关响应 HTML 是否使用了
标签。还可以对这些令牌变量执行条件测试,以确定对文本行执行操作的筛选器操作流。 操作分为三类:文本操作、条件测试和令牌设置。
文本操作
以下操作可对传递到操作的文本执行,并且可将该文本的变更版本传递到下一操作中。(注意:单击下表左边栏中的链接后,可能需要刷新才能访问登录页面。)
| ReplaceOperation 操作使用正则表达式模式来匹配和替换响应 HTML 行中的文本。ReplaceOperation 支持正则表达式后向引用和同时在模式字符串和替换字符串中使用令牌。 InsertOperation 可将文本插入 HTML 行的任何位置或文本有编号的行的前面。响应 HTML 开头和末尾的特殊行号值是“first”和“last”。InsertOperation 支持同时在设置的任何模式字符串和要插入的字符串中使用令牌。 DeleteOperation 可用来从响应中删除一行文本。一般只有在达到某种条件时才执行删除操作。 条件操作
以下操作在确定是否对文本行执行了子操作中起着监视作用。条件操作对响应文本行和令牌值执行条件测试。如果通过条件测试,则执行条件操作的子操作。
| MatchOperation 会尝试使用正则表达式模式匹配响应文本行。匹配模式的任何子操作都会对在响应文本行中找到的每个匹配项执行,而不是对整个文本行本身执行。MatchOperation 支持后向引用和在正则表达式模式中使用令牌。 测试文本行或令牌值是否符合逻辑测试条件。IfOperation 支持的测试有“exists”、“contains”和“equals”。如果 IfOperation 测试成功,将对整个文件行执行一遍 IfOperation 的子操作。 令牌设置操作
以下操作可以响应文本行中提取值,并将这些值设置为令牌映射中的变量。
| 将令牌值设置到令牌“映射”中。SetOperation 设置的值可包括令牌值。 GrabOperation 从与正则表达式模式匹配的文本行中取第一个字符串段并将其设置到令牌“映射”中。 此操作将抓取不跨越多行的标签的内部 HTML。例如,该操作可能会取文档头中 标签之间的值。 GrabAttributeOperation 取标签的属性值并将其设置到令牌“映射”中。 取整个文本行并将其设置到令牌“映射”中。 从令牌“映射”中删除令牌值。 其它操作
| 一旦执行此操作,将回送标签的内容。如果日志记录级别设置为“info”或“debug”,则回送的消息将仅显示在日志中。回送消息可能包含令牌值。 创建自定义筛选器操作
如果开发人员想对以上操作列表中未提到的响应 HTML 执行某种操作,PTPortletFilter 支持使用自定义 FilterOperation 对象。要创建自定义操作,开发人员必须创建 FilterOperation 类的子类并实现 execute() 方法。此外,开发人员可能要覆盖该类的 init() 方法,以对操作执行任何初始化。
要在 PTPortletFilter 配置 XML 文件中声明自定义操作,开发人员必须将以下 XML 添加到文件中:
... some value some other value foo bar ...
请注意,FilterOperation 的所有子类都支持内建的子操作,以上示例添加了自定义操作 MyCustomOperation 的 操作。但是,因为子操作的执行通常依赖于父操作的成功执行,如果创建自定义 FilterOperation 的开发人员想要对响应文本执行子操作,他们必须在 execute() 方法中调用 executeSubOperations() 方法。
标准令牌值
传递到 FilterOperation.execute() 方法中的令牌“映射”中包含几个由 PTPortletFilter 自动设置的令牌值。此外,还可以对 PTPortletFilter 进行设置,使特定设置类型(Admin、Community、Portlet 和 User 等)的所有值都可包括到令牌“映射”中。这样,筛选器操作可以引用作为被 PTPortletFilter 转换的 portlet 的部分首选项的令牌值。
标准令牌值包括:
| @LINE@ 筛选器操作正在处理的当前行号。 @TEXT@ 当前正在处理的响应 HTML 行的原始文本。 @RESULT@ 对传递到其中的文本(通常是来自 HTTP 响应的已修改文本行)执行的最后操作的结果。 @PORTLETID@ 当前 portlet 的 ID @COMMUNITYID@ 如果有,则为当前社区的 ID。 @PAGEID@ 如果有,则为当前页的 ID。 @IMAGESERVER@ URI 或门户 imageserver @STYLESHEET@ 门户 stylesheet 的 URL。 此外,开发人员还可以在 PTPortletFilter 的 web.xml 声明中设置初始化参数,如果参数设置为 true,则将特定设置类型的所有首选项包括到令牌“映射”中。这样可以使 portlet 设置控制 Web 应用的筛选方式。例如,可以设计一组筛选器操作,这些操作只有在令牌“映射”中找到特定首选项时才执行。这些初始化参数包括:
| admin.settings.tokens 如果设置为 true,则将 Admin 设置包括到令牌“映射”中。 community.settings.tokens 如果设置为 true,则将 Community 设置包括到令牌“映射”中。 communityportlet.settings.tokens 如果设置为 true,则将 CommunityPortlet 设置包括到令牌“映射”中。 portlet.settings.tokens 如果设置为 true,则将 Portlet 设置包括到令牌“映射”中。 user.settings.tokens 如果设置为 true,则将 User 设置包括到令牌“映射”中。 userinfo.settings.tokens 如果设置为 true,则将 UserInfo 设置包括到令牌“映射”中。 附录 B:PortletBean API
PortletBean 为编写专在 portlet 上运行的 Java Web 应用提供一套有用的工具。PortletBean 的 API 模拟 EDK IPortletRequest 接口和即将推出的 Plumtree 门户中发布的客户端 “PTPortlet” 对象 JavaScript。PortletBean 以属性形式自动附加到每个 HttpServletRequest。要从 JSP 或 servlet 访问 PortletBean ,开发人员可以使用以下静态方法:
PortletBean bean = PTPortletFilter.getPortlet(request);
虽然这种访问 PortletBean 的方法适用于 JSP scriptlet,但不适用于从 JSP 表达式语言中访问 PortletBean。在标准 JSP 表达式语言中,可使用以下语法引用 PortletBean:
... Click here 或者 Click here
最后,Java Server Faces与扩展的表达式语言包装在一起,可自动解析请求、会话或应用程序上下文中的JavaBean。
用于 EDK 功能的 PortletBean API
以下方法用作符合JavaBean的EDK功能包装器,该功能由 IPortletContext、IPortletRequest 和 IPortletResponse。如前所述,使用 EDK 功能的 JavaBean 包装器的主要优势是允许在 JSP 表达式语言中使用 PortletBean。(注意:单击下面表格左边栏的链接后,可能需要刷新浏览器才能访问登录页面。)
以下函数是获取 portlet 属性值的标准 getter/setter 函数:
- String getImageServerURI()
- String getStylesheetURL()
- String getHostPageURI()
- int getPortletID()
- int getCommunityID()
- int getPageID()
- String getPortalUUID()
- TimeZone getTimeZone()
- Boolean getIsGatewayed()
- Boolean getIsInCommunity()
除标准 getter 和 setter 外,PortletBean 还允许开发人员为 portlet 获取各种用来存储 portlet 首选项值的设置集合(Admin、Community、Portlet、CommunityPortlet、User 和 UserInfo)。在 EDK 中,这些设置值以打破标准 getter/setter 设计模式的方式进行检索和设置。具体来说,就是必须从 IPortletRequest 对象检索 portlet 设置并在 IPortletResponse 对象上进行设置。遗憾的是这种方式使得我们很难在 JSP 表达式语言中无缝地获取和设置 portlet 设置。要解决此问题,需创建一个 SettingsBean 对象,以提供 java.util.Map 接口来获取设置值并将这些值设置到特定设置集合中。SettingsBean 会扩展“映射”并覆盖标准的 put(Object key, Object value) 方法,使输入到“映射”中的项实际上设置在 IPortletResponse 上。以下方法允许用户访问每个 portlet 设置类型的 SettingsBean 对象:
- Map getAdminSettings()
- Map getCommunitySettings()
- Map getPortletSettings()
- Map getCommunityPortletSettings()
- Map getUserSettings()
- Map getUserInfoSettings()
SettingsBean 在 Java Server Faces 应用中尤其有用。将设置投射为“映射”可使 JSF 组件值绑定获取和设置不同的设置。简单地说,值绑定是具有 JavaBean 属性值(或本例中的“映射”条目)的 UI 组件的值之间的显式连接。例如,以下 JSF 代码:
确保显示时,标签生成的文本输入字段会显示自动填充到文本字段的 Admin 设置值“my.pref.value”。当文本字段所在的表单发送到服务器后,值绑定会自动从请求获取提交的文本字段值并将其设置为“my.pref.value” Admin 设置的值。
用于客户端功能的 PortletBean API
PortletBean 还提供了生成客户端JavaScript的方法,这些JavaScript可包含在 HTML 标签处理程序或内嵌于JSP 的脚本中。PortletBean 生成的脚本使得访问适应性 portlet 功能更为简单,从而方便地创建动态的多 portlet 应用。就当前版本而言,PortletBean API 支持三种类型的适应性 portlet 操作:触发 PCC 事件,获取会话首选项和设置会话首选项。PCC 事件是JavaScript事件,它由 portlet 触发并由在客户端 PCC 对象上注册的事件处理程序侦听。这些事件侦听程序可位于触发事件的 portlet 或者其它 portlet 中。
为 PortletBean 生成 API 的 JavaScript 具有以 JSP 表达式语句和 JSP scriptlet 生成 JavaScript 的方法。因此,开发人员可使以下类型的调用以 JSP scriptlet 生成 JavaScript:
<%= portlet.raiseEventJS("eventname") %> <%= portlet.raiseEventJS("mynamespace", "eventname") %> <%= portlet.raiseEventJS("mynamespace", "eventname", javaMap) %> <%= portlet.getSessionPrefJS("prefname") %> <%= portlet.getSessionPrefJS("namespace","prefname") %> <%= portlet.setSessionPrefJS("prefname","value") %> <%= portlet.setSessionPrefJS("namespace","prefname","value") %>
并使其生成以下 JavaScript:
document.PCC.RaiseEvent(‘urn://plumtree.com/adaptiveportlets‘, ‘eventname‘) document.PCC.RaiseEvent(‘mynamespace‘, ‘eventname‘) document.PCC.RaiseEvent(‘mynamespace‘, ‘eventname‘, {key:‘value‘, key2:‘value2‘}) document.PCC.GetSessionState(‘urn://plumtree.com/adaptiveportlets‘, ‘prefname‘) document.PCC.GetSessionState(‘mynamespace‘, ‘prefname‘) document.PCC.SetSessionState(‘urn://plumtree.com/adaptiveportlets‘, ‘prefname‘, ‘value‘) document.PCC.SetSessionState(‘mynamespace‘, ‘prefname‘, ‘value‘)
PortletBean 也具有生成属性的 JavaScript,可执行与以上 scriptlet 相同的功能,但使用的是 JSP 表达式语言。以下表达式语句也可生成上述 JavaScript:
${portlet.raiseEventJS[‘eventname‘]} ${portlet.raiseEventJS[‘mynamespace, eventname‘]} ${portlet.raiseEventJS[‘mynamespace, eventname, {key:value, key2:value2}‘]} ${portlet.getSessionPrefJS[‘prefname‘]} ${portlet.getSessionPrefJS[‘mynamespace, prefname‘]} ${portlet.setSessionPrefJS[‘prefname, value‘]} ${portlet.setSessionPrefJS[‘mynamespace, prefname, value‘]}
PortletBean 生成此 JavaScript 的方法是使用 JSP 表达式语言的属性生成机制。从技术上来说,表达式语言语句 ${portlet.getSessionPrefJS[‘mynamespace, prefname‘]} 读作“从包含在 PortletBean 中的 GetSessionPrefJS JavaBean 中获取名为‘mynamespace, prefname’的属性”。PortletBean 将‘mynamespace, prefname’属性名称字符串解析为 Java 对象自变量数组,而不是根据属性名称直接查找。例如,先将脚本字符串‘mynamespace, eventname, {key:value, key2:value2}’转换为具有两个字符串的对象数组和一个 Java 映射。然后将这些 Java 对象转换为相应 JavaScript 字符串以包含在客户端 JavaScript 的 document.PCC.RaiseEvent() 方法中。
这些参数字符串的语法规则如下:
- 除了对字符串定界的符号外,参数字符串中不能使用单引号或双引号。例如,portlet.raiseEventJS[‘foo"hello"bar‘] 是无效语句。
- 以花括号 ({}) 括起来的参数表示 JavaScript 关联数组,主要是关键字/值对散列。括号内的对以逗号分隔。关键字和值以字符“:”分隔,如 {key:value, key2:value2}。所有值都假定为字符串。
- 以方括号([])括起来的参数表示 JavaScript 数组。数组中的元素以逗号分隔,如 [first,second,third]。所有元素都假定为字符串。
- 以圆括号括起来的参数表示 JavaScript 对象引用。圆括号内的字符串将按原样显示,从而正确地引用页面上的 JavaScript 对象。例如,表达式语句 ${portlet.raiseEvent[‘ns, evtname, (window.event)‘]} 将生成以下 JavaScript:document.PCC.RaiseEvent(‘ns‘, ‘evtname‘, window.event)。如果有圆括号,则生成的 JavaScript 为:document.PCC.RaiseEvent(‘ns‘,‘evtname‘,‘window.event‘),只是简单地将字符串“window.event”作为事件对象而不是实际的 JavaScript 事件对象来传递。
- 所有其它参数均视为字符串
有关 PortletBean 生成的 JavaScript,必须注意一点:如果使用 标签来设置共享名称空间,并且没有指定名称空间自变量,则该名称空间将自动插入到生成的 JavaScript 中。将来的 Java Portlet Tools 版本将添加更多适应性 portlet JavaScript 生成器,为执行随处刷新和其它高级适应性 portlet 功能生成客户端 API JavaScript 方法。