先看一下在JSR168中提到的Portal page,可以了解一個Portal Page上大概有哪些element:

OK...進入本次主題

PSML:
PSML的全名是Portal Structure Markup Language。J2用PSML來定義Portal內的各種resource,包括Page、Folder、Link、Security、Menus等等,有關J2的PSML詳細介紹在此http://portals.apache.org/jetspeed-2/guides/guide-psml.html

這裡要特別提一下PSML Page。在J2中,一個PSML Page就代表一個Portal page,其根元素為<page>,裡面指定了這個Portal page所包含的portlet及排列方式(ex: 2行或3行)、這個Portal page所使用的樣板(稍後會提到的layout)還有這個Portal page的外觀(稍後會提到的decoration)等等。

另外一個要特別說明的是在PSML Page中所使用的<fragment>這個tag。fragment有portlet和layout二種,用type這個屬性來區別;<fragment type="portlet">代表一個portlet,<fragment type="layout">代表這個page所用的layout;然而不管是哪一種fragment,name屬性的值都應該依照"portlet-app-id::portlet-id"的格式。

以之前範例中的Sample.psml為例,根元素是<page>,所以這是一個PSML Page;第一個<fragment>是layout fragment,指定了這個page所使用的layout,name屬性的值為"jetspeed-layouts::VelocityTwoColumns"。第二個<fragment>就是範例的echo portlet,name屬性的值為"sample::EchoPortlet",就符合之前所描述的格式。

事實上,layout fragment其實也是portlet。看一下C:\tomcat\webapps\jetspeed\WEB-INF\apps\裡有一個jetspeed-layouts目錄,就是J2內部的一個Portlet application。因此"jetspeed-layouts::VelocityTwoColumns"會對到這個目錄下portlet-id為VelocityTwoColumns的portlet。總之,J2的layout也是portlet,如果再研究一下,其實還是個Velocity Bridge的portlet.

layout:
J2中的layout指的是用來排列Portal page中各個portlet的樣板。預設的情況下,J2用Velocity來實現layout

decoration:
J2中的decoration是用來裝飾Portal page和portlet使其美觀,分為layout-decoration和portlet-decoration兩種。layout-decoration負責一整個Portal page(因此叫page-decoration),而portlet-decoration負責每一個Portlet fragment。預設的情況下,J2用Velocity和CSS來實現decoration。當J2在呈現一Portal page時,會依照這個Portal page指定的layout來排列這個page上的各個portlet,並且使用這個page所指定的layout-decoration和portlet-decoration來美化這個page和所有的portlet。有關decoration的細節可參考http://portals.apache.org/jetspeed-2/guides/guide-decorators.html

Aggregator:
在J2中,一個Portal page的request最後通常會傳給一個Aggregator,然後由Aggregator負責跟Portal page內包含的所有portlet溝通並聚合各個portlet fragment以產生整個Portal page。以之前舉例的jetspeed-pipeline來說(C:\tomcat\webapps\jetspeed\WEB-INF\assembly\pipelines.xml),可以看到aggregatorValve這個bean被注入了org.apache.jetspeed.aggregator.PageAggregator這個Aggregator;再參考C:\tomcat\webapps\jetspeed\WEB-INF\assembly\aggregation.xml中,可已知道這個bean的實作是org.apache.jetspeed.aggregator.impl.PageAggregatorImpl。

來看一下這個PageAggregatorImpl的中用來產生Portal page的方法(部份省略修改):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 public void build( RequestContext context ){
//取得requested page
ContentPage page=context.getPage(); //取得 root fragment
ContentFragment root = page.getRootContentFragment(); //aggregate及render各個Portlet,基本上render的結果都寫到context裡
aggregateAndRender(root, context, page);
 
//將結果寫入response
context.getResponse().getWriter().write(root.getRenderedContent()); }

首先要注意一下傳入的是一個J2的RequestContext物件,基本上可以視為是用來存放這次request相關資訊的一個context;此外,可以把ContentFragement物件視為portlet。而其中第6行取得root fragment,實際上就是取得前面所說的layout fragment,也就是"jetspeed-layouts::VelocityTwoColumns"這個portlet。

接著再看一下第9行的aggregateAndRender()方法(部份省略修改):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
protected void aggregateAndRender( ContentFragment f, RequestContext context, ContentPage page ){
 
Iterator children = f.getContentFragments().iterator();
while (children.hasNext()){
ContentFragment child = (ContentFragment) children.next(); //遞迴
aggregateAndRender(child, context, page);
} // 開始真正做render的動作,基本上render的結果都寫到context裡
renderer.render(f, context); //renderer是org.apache.jetspeed.aggregator.impl.PortletRendererImpl //加上decoration
addStyle(context, f.getDecorator(),ContentFragment.PORTLET); }

由上面的code,可以了解到J2先把整個page上所有的portlet由外到內串起來,再由內到外一個一個做render的動作,而每render完一個portlet,就加上對應的decoration,直到做完整個page。

在第12行中,render的動作實際上是renderer透過Pluto來呼叫portlet(實際上是ContentFragment物件被包成portlet window)的render方法。PortletRendererImpl.render()這個方法裡使用了常見的Worker Thread和Observer樣式,以達到render多個portlet的功能,有興趣的不妨研究一下。

那如果想要新加外觀呢??最簡單的方式,就是先參考J2的layout portlet寫自已的layout,然後加入decoration。講起來容易,不過layout可是不太容易寫的,因為牽扯到的技術還蠻多,而且對J2也要有一定了解;但是如果能做出來,安裝就不會太麻煩。也許等以後J2紅起來以後,會有各式各樣的外觀可以玩吧...

其他參考資料:
Portal Design Doc : http://portals.apache.org/jetspeed-2/guides/guide-portal-design.html
簡介J2中有關Portal Page的一些概念

Jetspeed Power Tool (JPT) : http://portals.apache.org/jetspeed-2/guides/guide-jpt.html
開發layout和decoration時會用到

Portal Page的呈現的更多相关文章

  1. portal、portlet、portlet容器三个概念

    什么是portal Portlet规范中是这样定义portal的: A portal is a web based application that –commonly- provides perso ...

  2. Step-by-Step Guide to Portal Development for Microsoft Dynamics CRM - 摘自网络

    The Challenge Oftentimes in the world of Dynamics CRM, the need arises for non-CRM users to gain acc ...

  3. [转]How to mouse hover using Blue prism on a web page

    本文转自:https://stackoverflow.com/questions/53126436/how-to-mouse-hover-using-blue-prism-on-a-web-page/ ...

  4. Asp.net attributes collection

    <?xml version="1.0" encoding="utf-8"?><root>  <ContralNames>   ...

  5. facebook api介绍

    转自(http://sls.weco.net/node/10773) 一.Facebook API 基礎概念 Facebook API 概論 : API 最大的好處在於可以讓程式開發人員只需要根據 A ...

  6. ASP.NET MVC 5 實作 GridView 分頁

    本文用 ASP.NET MVC 5 實作一個 GridView,功能包括: 分頁(paging).關鍵字過濾(filtering).排序(sorting).AJAX 非同步執行,外觀上亦支援 Resp ...

  7. [R] [Johns Hopkins] R Programming 作業 Week 2 - Air Pollution

    Introduction For this first programming assignment you will write three functions that are meant to ...

  8. ScriptManager的几个属性和方法

    ScriptManager的几个属性和方法   一.EnablePageMethods ScriptManager的EnablePageMethods属性用于设定客户端javascript直接调用服务 ...

  9. SVG开发包, 20 个有用的 SVG 工具,提供更好的图像处理

    20 个有用的 SVG 工具,提供更好的图像处理 SVG 现正在 Web 设计领域变得越发流行, 你可以使用 Illustrator 或者 Inkscape 来创建 SVG 图像. 但当进行 Web ...

随机推荐

  1. magento csv导入

  2. Codeforces Round #376 (Div. 2) C. Socks---并查集+贪心

    题目链接:http://codeforces.com/problemset/problem/731/C 题意:有n只袜子,每只都有一个颜色,现在他的妈妈要去出差m天,然后让他每天穿第 L 和第 R 只 ...

  3. iOS 获取当前时间 年、月、日、周几

    NSDate * nowDate = [NSDate new]; NSCalendar *calendar = [NSCalendar currentCalendar]; NSUInteger uni ...

  4. 搜索框UISearchController的使用(iOS8.0以后替代UISearchBar + UISearchDisplayController)

    1.searchResultsUpdater:设置显示搜索结果的控制器 ? 1     _mySearchController.searchResultsUpdater = self; 2.dimsB ...

  5. Ubuntu 14.04安装OpenCV 3.1

    从OpenCV官网上下载OpenCV官网上下载OpenCV的未编译源代码: 点击这里 国内很多网络打开OpenCV官网速度缓慢,可以点击如下地址直接从GitHub上下载OpenCV 3.1的源代码 下 ...

  6. Keep Alive

    跳板机时经常出现连接被断开的情况.如果发生这种情况,请在客户端配置Keep Alive设置,具体方法参考如下: Windows: secureCRT:Properties -> Terminal ...

  7. dede让channelartlist标签支持currentstyle属性 完美解决

    打开include\taglib\channelartlist.lib.php 找到 $pv->Fields['typeurl'] = GetOneTypeUrlA($typeids[$i]); ...

  8. PHP的日期和时间

    <?php //2.获取日期和时间 //时间是一维的,所以任何一个时间的时间戳都是不一样的 //array getdate([int timestamp]); //string date(str ...

  9. ext4.1Grid中的column多选

    ext4.1中默认单选可以使用checkboxmodel实现多选selModel:Ext.create('Ext.selection.CheckboxModel'),

  10. idea 的问题

    IDEA的maven项目中,默认源代码目录下的xml等资源文件并不会在编译的时候一块打包进classes文件夹,而是直接舍弃掉. 如果使用的是Eclipse,Eclipse的src目录下的xml等资源 ...