// portlet选择
/html/portlet/layout_configuration/view.jsp
<%
PortletCategory portletCategory = (PortletCategory)WebAppPool.get(
company.getCompanyId(), WebKeys.PORTLET_CATEGORY);
// 读取所有的portlet根类别.
List categories = ListUtil.fromCollection(portletCategory.getCategories());
// 排序,
Collections.sort(categories, new PortletCategoryComparator(company.getCompanyId(), locale));
Iterator itr = categories.iterator();
while (itr.hasNext()) {
request.setAttribute(WebKeys.PORTLET_CATEGORY, itr.next());
%>
<liferay-util:include page="/html/portlet/layout_configuration/view_category.jsp" />
<% } %>
/html/portlet/layout_configuration/view-category.jsp
<%
PortletCategory portletCategory = (PortletCategory)request.getAttribute(WebKeys.PORTLET_CATEGORY);
String oldCategoryPath = (String)request.getAttribute(WebKeys.PORTLET_CATEGORY_PATH);
String newCategoryPath = LanguageUtil.get(pageContext, portletCategory.getName());
if (Validator.isNotNull(oldCategoryPath)) {
newCategoryPath = oldCategoryPath + ":" + newCategoryPath;
}
// 读取子类别,
List categories = ListUtil.fromCollection(portletCategory.getCategories());
// 排序
Collections.sort(categories, new PortletCategoryComparator(company.getCompanyId(), locale));
List portlets = new ArrayList();
// 读取类别下的所有portlet定义。
Iterator itr1 = portletCategory.getPortlets().iterator();
while (itr1.hasNext()) {
String portletId = (String)itr1.next();
Portlet portlet = PortletLocalServiceUtil.getPortletById(user.getCompanyId(), portletId);
if (portlet != null) { // 检查portlet是否为可选择的?
if (portlet.isSystem()) {
}
else if (!portlet.isActive()) {
}
else if (!portlet.isInstanceable() && layoutTypePortlet.hasPortletId(portlet.getPortletId())) {
}
else if (!portlet.hasAddPortletPermission(user.getUserId())) {
}
else {
portlets.add(portlet);
}
}
}
// 排序.
Collections.sort(portlets, new PortletTitleComparator(application, locale));
if ((categories.size() > 0) || (portlets.size() > 0)) {
%>
<div class="layout_configuration_category_pane" style="display: none;">
<%
// 遍历子类别.
Iterator itr2 = categories.iterator();
while (itr2.hasNext()) {
request.setAttribute(WebKeys.PORTLET_CATEGORY, itr2.next());
request.setAttribute(WebKeys.PORTLET_CATEGORY_PATH, newCategoryPath);
%>
<liferay-util:include page="/html/portlet/layout_configuration/view_category.jsp" />
<%
request.setAttribute(WebKeys.PORTLET_CATEGORY_PATH, oldCategoryPath);
}
itr2 = portlets.iterator();
while (itr2.hasNext()) {
// 输出可选择的portlet.
Portlet portlet = (Portlet)itr2.next();
%>
<div class="layout_configuration_portlet" id="<%= newCategoryPath %>:<%= PortalUtil.getPortletTitle(portlet, application, locale) %>">
<table border="0" cellpadding="2" cellspacing="0" width="100%">
<tr>
<td width="99%">
<%= PortalUtil.getPortletTitle(portlet, application, locale) %></td>
<td align="right">
<input class="portlet-form-button" type="button" value="<%= LanguageUtil.get(pageContext, "add") %>"
onClick="
addPortlet('<%= plid %>', '<%= portlet.getPortletId() %>');
if (<%= !portlet.isInstanceable() %>) {
var div = document.getElementById('<%= StringUtil.replace(newCategoryPath + ":" + PortalUtil.getPortletTitle(portlet, application, locale), "'", "//'") %>');
div.parentNode.removeChild(div);
};">
</td>
</tr>
</table>
</div>
<% } %>
</div>
<% } %>
// 更新layout.
com.com.liferay.portal.action.UpdateLayoutAction
public class UpdateLayoutAction extends Action {
public ActionForward execute(
ActionMapping mapping, ActionForm form, HttpServletRequest req,
HttpServletResponse res)
throws Exception {
Layout layout = (Layout)req.getAttribute(WebKeys.LAYOUT);
LayoutTypePortlet layoutTypePortlet =
(LayoutTypePortlet)layout.getLayoutType();
String cmd = ParamUtil.getString(req, Constants.CMD);
String portletId = ParamUtil.getString(req, "p_p_id");
if (cmd.equals(Constants.ADD)) { // 添加portlet到layout.
portletId = layoutTypePortlet.addPortletId(
req.getRemoteUser(), portletId);
}
else if (cmd.equals(Constants.DELETE)) { // 从layout删除指定portlet.
layoutTypePortlet.removePortletId(portletId);
}
else if (cmd.equals("minimize")) { // portlet最小化.
boolean restore = ParamUtil.getBoolean(req, "p_p_restore");
if (restore) {
layoutTypePortlet.removeStateMinPortletId(portletId);
}
else {
layoutTypePortlet.addStateMinPortletId(portletId);
}
}
else if (cmd.equals("move")) { // 移动portlet的位置.
String columnId = ParamUtil.getString(req, "p_p_col_id");
int columnPos = ParamUtil.getInteger(req, "p_p_col_pos");
layoutTypePortlet.movePortletId(
req.getRemoteUser(), portletId, columnId, columnPos);
}
else if (cmd.equals("template")) { // 更改layout的模板.
String layoutTemplateId = ParamUtil.getString(
req, "layoutTemplateId");
layoutTypePortlet.setLayoutTemplateId(layoutTemplateId);
}
// 更新到数据库.
LayoutServiceUtil.updateLayout(
layout.getLayoutId(), layout.getOwnerId(),
layout.getTypeSettings());
if (ParamUtil.getBoolean(req, "refresh")) {
return mapping.findForward(Constants.COMMON_REFERER);
}
else {
if (cmd.equals(Constants.ADD) && (portletId != null)) {
// 输出portlet.
}
return null;
}
}
}
// layout的应用,
/html/portal/layout/view/portlet.jsp
<%
boolean layoutMaximized = layoutTypePortlet.hasStateMax();
if (!layoutMaximized) {
String content = LayoutTemplateLocalUtil.getContent(
layoutTypePortlet.getLayoutTemplateId(), false, theme.getThemeId());
RuntimePortletUtil.processTemplate(application,
pageContext, request, response, content);
}
else {
String content = LayoutTemplateLocalUtil.getContent(
"max", true, theme.getThemeId());
RuntimePortletUtil.processTemplate(
application, pageContext, request, response,
StringUtil.split(layoutTypePortlet.getStateMax())[0], content);
}
List columns = layoutTypePortlet.getLayoutTemplate().getColumns();
%>
上面使用到的layoutTypePortlet是通过自定义Tag来定义的,
有关portlet的输出处理请参考本站的liferay流程处理一文。
// layout相关对象的定义,
在/html/common/init.jsp中有如下定义:
<liferay-theme:defineObjects />
com.liferay.taglib.theme.DefineObjectsTag
public class DefineObjectsTag extends TagSupport {
public int doStartTag() {
ServletRequest req = pageContext.getRequest();
ThemeDisplay themeDisplay =
(ThemeDisplay)req.getAttribute(WebKeys.THEME_DISPLAY);
if (themeDisplay != null) {
pageContext.setAttribute("themeDisplay", themeDisplay);
pageContext.setAttribute("company", themeDisplay.getCompany());
pageContext.setAttribute("account", themeDisplay.getAccount());
pageContext.setAttribute("user", themeDisplay.getUser());
pageContext.setAttribute("contact", themeDisplay.getContact());
if (themeDisplay.getLayout() != null) {
pageContext.setAttribute("layout", themeDisplay.getLayout());
}
if (themeDisplay.getLayouts() != null) {
pageContext.setAttribute("layouts", themeDisplay.getLayouts());
}
pageContext.setAttribute("plid", themeDisplay.getPlid());
if (themeDisplay.getLayoutTypePortlet() != null) {
pageContext.setAttribute(
"layoutTypePortlet", themeDisplay.getLayoutTypePortlet());
}
pageContext.setAttribute(
"portletGroupId", themeDisplay.getPortletGroupId());
pageContext.setAttribute(
"permissionChecker", themeDisplay.getPermissionChecker());
pageContext.setAttribute("locale", themeDisplay.getLocale());
pageContext.setAttribute("timeZone", themeDisplay.getTimeZone());
pageContext.setAttribute("theme", themeDisplay.getTheme());
pageContext.setAttribute(
"colorScheme", themeDisplay.getColorScheme());
pageContext.setAttribute(
"portletDisplay", themeDisplay.getPortletDisplay());
}
return SKIP_BODY;
}
}
上面定义了themeDisplay, layout, portletDiaplay, locale, timeZone等与UI相关的对象.
// layout相关对象的读取,
layout相关对象是在服务前置处理事件ServicePreAction中初始化的,事件(Event)是liferay中的一种扩展机制。
com.liferay.portal.events.ServicePreAction
public class ServicePreAction extends Action {
public void run(HttpServletRequest req, HttpServletResponse res)
throws ActionException {
try {
HttpSession ses = req.getSession();
// Company
Company company = PortalUtil.getCompany(req);
String companyId = company.getCompanyId();
// Paths
String contextPath = PrefsPropsUtil.getString(
companyId, PropsUtil.PORTAL_CTX);
if (contextPath.equals(StringPool.SLASH)) {
contextPath = StringPool.BLANK;
}
String rootPath = (String)req.getAttribute(WebKeys.ROOT_PATH);
String mainPath = (String)req.getAttribute(WebKeys.MAIN_PATH);
String friendlyURLPrivatePath =
(String)req.getAttribute(WebKeys.FRIENDLY_URL_PRIVATE_PATH);
String friendlyURLPublicPath =
(String)req.getAttribute(WebKeys.FRIENDLY_URL_PUBLIC_PATH);
String imagePath = (String)req.getAttribute(WebKeys.IMAGE_PATH);
// Company logo
String companyLogo =
imagePath + "/company_logo?img_id=" + companyId;
// User
User user = null;
try {
user = PortalUtil.getUser(req);
}
catch (NoSuchUserException nsue) {
return;
}
// Is the user signed in? (用户是否登录?)
boolean signedIn = false;
if (user == null) {
user = company.getDefaultUser();
}
else {
signedIn = true;
}
// Permission checker (权限检查器)
PermissionChecker permissionChecker =
PermissionCheckerFactory.create(user, signedIn, true);
PermissionThreadLocal.setPermissionChecker(permissionChecker);
// Locale (语言)
Locale locale = (Locale)ses.getAttribute(Globals.LOCALE_KEY);
// Cookie support - cookie支持
CookieKeys.addSupportCookie(res);
// Time zone (时区)
TimeZone timeZone = user.getTimeZone();
if (timeZone == null) {
timeZone = company.getTimeZone();
}
// Layouts (布局)
if (signedIn) {
boolean layoutsRequired = user.isLayoutsRequired();
if (layoutsRequired) {
addDefaultLayouts(user);
}
else {
deleteDefaultLayouts(user);
}
}
Layout layout = null;
List layouts = null;
String plid = ParamUtil.getString(req, "p_l_id");
String layoutId = Layout.getLayoutId(plid);
String ownerId = Layout.getOwnerId(plid);
if ((layoutId != null) && (ownerId != null)) {
try {
layout = LayoutLocalServiceUtil.getLayout(
layoutId, ownerId);
if (!isViewableCommunity(user, ownerId)) {
layout = null;
}
else {
layouts = LayoutLocalServiceUtil.getLayouts(
ownerId, Layout.DEFAULT_PARENT_LAYOUT_ID);
}
}
catch (NoSuchLayoutException nsle) {
}
}
if (layout == null) {
Object[] defaultLayout = getDefaultLayout(user, signedIn);
layout = (Layout)defaultLayout[0];
layouts = (List)defaultLayout[1];
}
Object[] viewableLayouts = getViewableLayouts(
layout, layouts, permissionChecker, req);
layout = (Layout)viewableLayouts[0];
layouts = (List)viewableLayouts[1];
if (layout != null) {
plid = layout.getPlid();
layoutId = layout.getLayoutId();
ownerId = layout.getOwnerId();
}
if ((layout != null) && layout.isShared()) {
layout = (Layout)layout.clone();
}
LayoutTypePortlet layoutTypePortlet = null;
if (layout != null) {
req.setAttribute(WebKeys.LAYOUT, layout);
req.setAttribute(WebKeys.LAYOUTS, layouts);
layoutTypePortlet = (LayoutTypePortlet)layout.getLayoutType();
if (layout.isPrivateLayout()) {
permissionChecker.setCheckGuest(false);
}
}
String portletGroupId = PortalUtil.getPortletGroupId(plid);
// Theme and color scheme (主题和色彩)
Theme theme = null;
ColorScheme colorScheme = null;
if (layout != null) {
theme = layout.getTheme();
colorScheme = layout.getColorScheme();
}
else {
theme = ThemeLocalUtil.getTheme(
companyId,
PrefsPropsUtil.getString(
companyId, PropsUtil.DEFAULT_THEME_ID));
colorScheme = ThemeLocalUtil.getColorScheme(
companyId, theme.getThemeId(),
PrefsPropsUtil.getString(
companyId, PropsUtil.DEFAULT_COLOR_SCHEME_ID));
}
req.setAttribute(WebKeys.THEME, theme);
req.setAttribute(WebKeys.COLOR_SCHEME, colorScheme);
// Resolution
int resolution = Resolution.FULL_RESOLUTION;
String resolutionKey = user.getResolution();
if (resolutionKey.equals(Resolution.S1024X768_KEY)) {
resolution = Resolution.S1024X768_RESOLUTION;
}
else if (resolutionKey.equals(Resolution.S800X600_KEY)) {
resolution = Resolution.S800X600_RESOLUTION;
}
// Theme display
String protocol = Http.getProtocol(req) + "://";
ThemeDisplay themeDisplay = ThemeDisplayFactory.create();
themeDisplay.setCompany(company);
themeDisplay.setCompanyLogo(companyLogo);
themeDisplay.setUser(user);
themeDisplay.setLayout(layout);
themeDisplay.setLayouts(layouts);
themeDisplay.setPlid(plid);
themeDisplay.setLayoutTypePortlet(layoutTypePortlet);
themeDisplay.setPortletGroupId(portletGroupId);
themeDisplay.setSignedIn(signedIn);
themeDisplay.setPermissionChecker(permissionChecker);
themeDisplay.setLocale(locale);
themeDisplay.setTimeZone(timeZone);
themeDisplay.setLookAndFeel(contextPath, theme, colorScheme);
themeDisplay.setResolution(resolution);
themeDisplay.setStatePopUp(LiferayWindowState.isPopUp(req));
themeDisplay.setPathApplet(contextPath + "/applets");
themeDisplay.setPathContext(contextPath);
themeDisplay.setPathFlash(contextPath + "/flash");
themeDisplay.setPathFriendlyURLPrivate(friendlyURLPrivatePath);
themeDisplay.setPathFriendlyURLPublic(friendlyURLPublicPath);
themeDisplay.setPathImage(imagePath);
themeDisplay.setPathJavaScript(contextPath + "/html/js");
themeDisplay.setPathMain(mainPath);
themeDisplay.setPathRoot(rootPath);
themeDisplay.setPathSound(contextPath + "/html/sound");
// URLs
themeDisplay.setShowAddContentIcon(false);
themeDisplay.setShowHomeIcon(true);
themeDisplay.setShowMyAccountIcon(signedIn);
themeDisplay.setShowPageSettingsIcon(false);
themeDisplay.setShowPortalIcon(true);
themeDisplay.setShowSignInIcon(!signedIn);
themeDisplay.setShowSignOutIcon(signedIn);
themeDisplay.setURLHome(protocol + company.getHomeURL());
if (layout != null) {
boolean hasManageLayoutsPermission =
GroupPermission.contains(
permissionChecker, portletGroupId,
ActionKeys.MANAGE_LAYOUTS);
boolean hasUpdateLayoutPermission =
LayoutPermission.contains(
permissionChecker, layout, ActionKeys.UPDATE);
if (hasManageLayoutsPermission || hasUpdateLayoutPermission) {
themeDisplay.setShowAddContentIcon(true);
themeDisplay.setURLAddContent(
"LayoutConfiguration.toggle('" +
PortletKeys.LAYOUT_CONFIGURATION + "', '" + plid +
"', '" + mainPath + "','" +
themeDisplay.getPathThemeImage() + "');");
}
if (hasManageLayoutsPermission) {
themeDisplay.setShowPageSettingsIcon(true);
PortletURL pageSettingsURL = new PortletURLImpl(
req, PortletKeys.LAYOUT_MANAGEMENT, plid, false);
pageSettingsURL.setWindowState(WindowState.MAXIMIZED);
pageSettingsURL.setPortletMode(PortletMode.VIEW);
pageSettingsURL.setParameter(
"struts_action", "/layout_management/edit_pages");
if (layout.isPrivateLayout()) {
pageSettingsURL.setParameter("tabs2", "private");
}
else {
pageSettingsURL.setParameter("tabs2", "public");
}
pageSettingsURL.setParameter("groupId", portletGroupId);
pageSettingsURL.setParameter("selPlid", plid);
themeDisplay.setURLPageSettings(pageSettingsURL);
}
PortletURL myAccountURL = new PortletURLImpl(
req, PortletKeys.MY_ACCOUNT, plid, false);
myAccountURL.setWindowState(WindowState.MAXIMIZED);
myAccountURL.setPortletMode(PortletMode.VIEW);
myAccountURL.setParameter(
"struts_action", "/my_account/edit_user");
themeDisplay.setURLMyAccount(myAccountURL);
}
themeDisplay.setURLPortal(protocol + company.getPortalURL());
themeDisplay.setURLSignIn(mainPath + "/portal/login");
themeDisplay.setURLSignOut(
mainPath + "/portal/logout?referer=" + mainPath);
req.setAttribute(WebKeys.THEME_DISPLAY, themeDisplay);
// Fix state
fixState(req, themeDisplay);
}
catch (Exception e) {
_log.error(StackTraceUtil.getStackTrace(e));
throw new ActionException(e);
}
}
}