zoukankan      html  css  js  c++  java
  • Liferay7 BPM门户开发之37: Liferay7下的OSGi Hook集成开发

    hook开发是Liferay客制扩展的一种方式,比插件灵活,即可以扩展liferay门户,也能对原有特性进行更改,Liferay有许多内置的服务,比如用hook甚至可以覆盖Liferay服务。

    可作为系统服务挂钩(Liferay Service Hook),还有其他类型的hook...

    Liferay6.2 时的hook开发比较有限,而在Liferay7则大为不同,OSGi services的彻底改进至Liferay的底层模型框架,使得Liferay可以支持更多的定制扩展!
    OSGi plugins可以快速部署到Liferay,就和其他类型的插件一样。

    名词:

    FQPN: a fully qualified portlet name

    正在不断整理完善中...

    PollerProcessor

    com.liferay.portal.kernel.poller.PollerProcessor
    集成点:"javax.portlet.name" : a FQPN
    用途: 轮训消息机制,用于类似Ajax在页面显示信息
    例子:
    JS:

    AUI()
    .use('aui-base','aui-delayed-task',    'liferay-poller',
    function(A) {
    
    Liferay.namespace('BladePoller');
    
    Liferay.BladePoller.Manager = {
    init: function() {
    
    var instance = this;
    
    instance._portletId = A.one("#pollerPortletId").val();
    
    instance._bladePollerContainer = A.one('#bladePollerContainer');
    
    
    console.log("Init: portletId:"+instance._portletId+
    ", containerId:"+instance._bladePollerContainer);
    
    instance._updateTask = new A.debounce(instance._updateMessage,30000,
    instance);
    
    instance._updateTask.delay(0);
    
    Liferay.Poller.addListener(instance._portletId,instance._onPollerUpdate, instance);
    
    Liferay.on(
    'sessionExpired',
    function(event) {
    Liferay.Poller.removeListener(instance._portletId);
    instance._bladePollerContainer.hide();
    }
    );
    
    },
    
    send: function(options, id) {
    
    console.log("Options:" + options + ", id:" + id);
    
    var instance = this;
    
    Liferay.Poller.submitRequest(instance._portletId, options, id);
    
    instance._updateTask();
    },
    
    _updateMessage: function() {
    console.log("Update Message");
    var instance = this;
    instance.send(    {
    status : 'OK'
    });
    },
    
    _onPollerUpdate : function(response, chunkId) {
    
    console.log("updating...");
    
    var instance = this;
    
    instance._bladePollerContainer.text(response.content.message);
    
    instance._bladePollerContainer.show();
    
    instance.send(
    {
    status : 'OK'
    }
    );
    
    }
    
    };
    
    A.augment(Liferay.BladePoller.Manager, A.Attribute, true);
    
    Liferay.publish(
    'pollerPortletReady',
    {
    defaultFn: A.bind('init', Liferay.BladePoller.Manager),
    fireOnce: true
    }
    );
    
    A.on(
    'domready',
    function() {
    Liferay.fire('pollerPortletReady');
    }
    );
    
    }
    
    );
    View Code

    jsp:

    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
    
    <%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
    
    <%@ taglib uri="http://liferay.com/tld/aui" prefix="aui" %><%@
    taglib uri="http://liferay.com/tld/portlet" prefix="liferay-portlet" %><%@
    taglib uri="http://liferay.com/tld/theme" prefix="liferay-theme" %><%@
    taglib uri="http://liferay.com/tld/ui" prefix="liferay-ui" %>
    
    <liferay-theme:defineObjects />
    
    <portlet:defineObjects />
    <p>
    <b><liferay-ui:message
    key="blade_portlet_BladePollProcessorPortlet.title" /></b>
    </p>
    
    <input id="pollerPortletId" type="hidden" value="<%= portletDisplay.getId() %>" />
    
    <p id="bladePollerContainer"></p>
    View Code

    Java:

    import com.liferay.portal.kernel.portlet.bridges.mvc.MVCPortlet;
    import javax.portlet.Portlet;
    import org.osgi.service.component.annotations.Component;
    
    @Component(
    immediate = true,
    property = {
    "com.liferay.portlet.css-class-wrapper=portlet-pollprocessor-blade",
    "com.liferay.portlet.display-category=category.sample",
    "com.liferay.portlet.header-portlet-javascript=/js/main.js",
    "com.liferay.portlet.poller-processor-class=blade.portlet.BladePollProcessor",
    "com.liferay.portlet.private-request-attributes=false",
    "com.liferay.portlet.private-session-attributes=false",
    "com.liferay.portlet.remoteable=true",
    "com.liferay.portlet.render-weight=50",
    "javax.portlet.display-name=BLADE PollProcessor",
    "javax.portlet.expiration-cache=0",
    "javax.portlet.init-param.template-path=/",
    "javax.portlet.init-param.view-template=/view.jsp",
    "javax.portlet.portlet.info.keywords=blade,pollprocessor",
    "javax.portlet.portlet.info.short-title=BLADE PollProcessor",
    "javax.portlet.portlet.info.title=BLADE PollProcessor",
    "javax.portlet.resource-bundle=content.Language",
    "javax.portlet.security-role-ref=power-user,user"
    },
    service = Portlet.class
    )
    public class BladePollProcessorPortlet extends MVCPortlet {
    }
    
    
    import com.liferay.portal.kernel.json.JSONFactoryUtil;
    import com.liferay.portal.kernel.json.JSONObject;
    import com.liferay.portal.kernel.log.Log;
    import com.liferay.portal.kernel.log.LogFactoryUtil;
    import com.liferay.portal.kernel.poller.BasePollerProcessor;
    import com.liferay.portal.kernel.poller.DefaultPollerResponse;
    import com.liferay.portal.kernel.poller.PollerProcessor;
    import com.liferay.portal.kernel.poller.PollerRequest;
    import com.liferay.portal.kernel.poller.PollerResponse;
    import java.util.Date;
    import org.osgi.service.component.annotations.Component;
    
    @Component(
    immediate = true,
    property = {"javax.portlet.name=blade_portlet_BladePollProcessorPortlet"},
    service = PollerProcessor.class
    )
    public class BladePollProcessor extends BasePollerProcessor {
    
    @Override
    protected PollerResponse doReceive(PollerRequest pollerRequest)
    throws Exception {
    
    if (_log.isDebugEnabled()) {
    _log.debug("Recevied the poller request" + pollerRequest);
    }
    
    JSONObject responseJSON = JSONFactoryUtil.createJSONObject();
    PollerResponse pollerResponse = new DefaultPollerResponse();
    responseJSON.put(
    "message", "Hello from BLADE Poller, time now is:" + new Date());
    pollerResponse.setParameter("content", responseJSON);
    
    return pollerResponse;
    }
    
    @Override
    protected void doSend(PollerRequest pollerRequest) throws Exception {
    String status = getString(pollerRequest, "status");
    
    if (_log.isInfoEnabled()) {
    _log.info("Poller status:" + status);
    }
    }
    
    private final Log _log = LogFactoryUtil.getLog(BladePollProcessor.class);
    
    }
    View Code

    ===================

    AuthFailure & Authenticator

    com.liferay.portal.security.auth.AuthFailure
    集成点:"key" : "auth.failure" | "auth.max.failures"
    用途: 用户登录失败处理

    com.liferay.portal.security.auth.Authenticator
    集成点:"key" : "auth.pipeline.post" | "auth.pipeline.post"
    用途: 用户登录验证
    例子:

    Liferay7 BPM门户开发之32: 实现自定义认证登陆(定制Authentication Hook)


    ===================


    StrutsAction & StrutsPortletAction


    com.liferay.portal.kernel.struts.StrutsAction
    集成点:"path" : a struts path (starting with "/portal")
    用途: HttpServletRequest方式的Struts Action跳转

    com.liferay.portal.kernel.struts.StrutsPortletAction
    集成点:"path" : a portlet struts path
    用途: StrutsPortletAction方式的Struts Action跳转

    StrutsAction和StrutsPortletAction都不是官方推荐方式

    例子:

    @Component(
        immediate = true, property = {"path=/login/login"},
        service = StrutsPortletAction.class
    )
    public class BladePortletAction extends BaseStrutsPortletAction {
    
        @Override
        public void processAction(
                StrutsPortletAction originalStrutsPortletAction,
                PortletConfig portletConfig, ActionRequest actionRequest,
                ActionResponse actionResponse)
            throws Exception {
    
            if (_log.isDebugEnabled()) {
                _log.debug("BladePortletAction - procesAction");
            }
    
            ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
                WebKeys.THEME_DISPLAY);
    
            User loggedinUser = themeDisplay.getUser();
    
            if ((loggedinUser != null) && _log.isInfoEnabled()) {
                _log.info(
                    "Logging in with user:[" + loggedinUser.getFirstName() + " " +
                        loggedinUser.getLastName() + "]");
    
                _log.info(
                    "Logged in user: Current Greetings[" +
                        loggedinUser.getGreeting() + "]");
            }
    
            originalStrutsPortletAction.processAction(
                originalStrutsPortletAction, portletConfig, actionRequest,
                actionResponse);
        }
    
        @Override
        public String render(
                StrutsPortletAction originalStrutsPortletAction,
                PortletConfig portletConfig, RenderRequest renderRequest,
                RenderResponse renderResponse)
            throws Exception {
    
            if (_log.isDebugEnabled()) {
                _log.debug("BladePortletAction - render");
            }
    
            ThemeDisplay themeDisplay = (ThemeDisplay)renderRequest.getAttribute(
                WebKeys.THEME_DISPLAY);
    
            User loggedinUser = themeDisplay.getUser();
    
            if (loggedinUser != null) {
                loggedinUser.setLastName("BLADE");
    
                loggedinUser.setGreeting(
                    "Hello," + loggedinUser.getFirstName() + " from BLADE!");
    
                _userLocalService.updateUser(loggedinUser);
            }
    
            return originalStrutsPortletAction.render(
                originalStrutsPortletAction, portletConfig, renderRequest,
                renderResponse);
        }
    
        @Override
        public void serveResource(
                StrutsPortletAction originalStrutsPortletAction,
                PortletConfig portletConfig, ResourceRequest resourceRequest,
                ResourceResponse resourceResponse)
            throws Exception {
    
            if (_log.isDebugEnabled()) {
                _log.debug("BladePortletAction - serveResource");
            }
    
            originalStrutsPortletAction.serveResource(
                originalStrutsPortletAction, portletConfig, resourceRequest,
                resourceResponse);
        }
    
        @Reference(unbind = "-")
        public void setUserService(UserLocalService userService) {
            _userLocalService = userService;
        }
    
        private static final Log _log = LogFactoryUtil.getLog(
            BladePortletAction.class);
    
        private UserLocalService _userLocalService;
    
    }
    View Code

    ===================

    ResourceBundle


    java.util.ResourceBundle
    集成点:"javax.portlet.name" : a FQPN
    用途: 用于国际化字符串
    例子:https://dev.liferay.com/develop/tutorials/-/knowledge_base/7-0/localizing-your-application

    demo:

    import com.liferay.portal.kernel.language.UTF8Control;
    import java.util.Enumeration;
    import java.util.ResourceBundle;
    import org.osgi.service.component.annotations.Component;
    
    @Component(
        immediate = true, property = {"language.id=en_US"},
        service = ResourceBundle.class
    )
    public class CustomResourceBundle extends ResourceBundle {
    
        @Override
        public Enumeration<String> getKeys() {
            return _resourceBundle.getKeys();
        }
    
        @Override
        protected Object handleGetObject(String key) {
            return _resourceBundle.getObject(key);
        }
    
        private final ResourceBundle _resourceBundle = ResourceBundle.getBundle(
            "content.Language", UTF8Control.INSTANCE);
    
    }
    View Code

    ===================

    ActionCommand

    com.liferay.util.bridges.mvc.ActionCommand
    集成点:"action.command.name" : an MVCPortlet action command name
    集成点:"javax.portlet.name" : a FQPN
    用途: Action周期处理

    定义:https://docs.liferay.com/portal/7.0/javadocs/portal-kernel/com/liferay/portal/kernel/portlet/bridges/mvc/BaseMVCActionCommand.html#doProcessAction(javax.portlet.ActionRequest,%20javax.portlet.ActionResponse))

    例子:https://dev.liferay.com/develop/tutorials/-/knowledge_base/7-0/mvc-action-command

    demo:

    @Component(
        immediate = true,
        property = {
            "javax.portlet.name=com_liferay_blade_samples_portlet_actioncommand_GreeterPortlet",
            "mvc.command.name=greet"
        },
        service = MVCActionCommand.class
    )
    public class GreeterActionCommand implements MVCActionCommand {
    
        @Override
        public boolean processAction(
                ActionRequest actionRequest, ActionResponse actionResponse)
            throws PortletException {
    
            _handleActionCommand(actionRequest);
    
            return true;
        }
    
        private void _handleActionCommand(ActionRequest actionRequest) {
            String name = ParamUtil.get(actionRequest, "name", StringPool.BLANK);
    
            if (_log.isInfoEnabled()) {
                _log.info("Hello " + name);
            }
    
            String greetingMessage = "Hello " + name + "! Welcome to OSGi";
    
            actionRequest.setAttribute("GREETER_MESSAGE", greetingMessage);
    
            SessionMessages.add(actionRequest, "greetingMessage", greetingMessage);
        }
    
        private static final Log _log = LogFactoryUtil.getLog(
            GreeterActionCommand.class);
    
    }
    View Code

    ===================

    Filter

    javax.portlet.filter.ActionFilter

    javax.portlet.filter.EventFilter

    javax.portlet.filter.RenderFilter

    javax.portlet.filter.ResourceFilter

    集成点:"javax.portlet.name" : a FQPN

    例子:

    Liferay7 BPM门户开发之36: 使用Portlet filters过滤器做切面AOP

    ===================

    Social

    com.liferay.portlet.social.model.SocialActivityInterpreter
    集成点:"javax.portlet.name" : a FQPN
    用途: 
    例子:

    com.liferay.portlet.social.model.SocialRequestInterpreter
    集成点:"javax.portlet.name" : a FQPN
    用途: 
    例子:

    ===================

    AssetRendererFactory

    com.liferay.portlet.asset.model.AssetRendererFactory
    集成点:"javax.portlet.name" : a FQPN
    用途:
    例子:

    ===================

    AtomCollectionAdapter

    com.liferay.portal.kernel.atom.AtomCollectionAdapter<?>
    集成点:"javax.portlet.name" : a FQPN
    用途:
    例子:

    ===================

    ConfigurationAction

    com.liferay.portal.kernel.portlet.ConfigurationAction
    集成点:"javax.portlet.name" : a FQPN
    用途: 配置动作扩展
    例子:https://dev.liferay.com/develop/tutorials/-/knowledge_base/7-0/implementing-configuration-actions

    ===================

    ControlPanelEntry

    com.liferay.portlet.ControlPanelEntry
    集成点:"javax.portlet.name" : a FQPN
    用途:
    例子:

    ===================

    CustomAttributesDisplay

    com.liferay.portlet.expando.model.CustomAttributesDisplay
    集成点:"javax.portlet.name" : a FQPN
    用途:
    例子:

    ===================

    com.liferay.portlet.dynamicdatamapping.util.DDMDisplay
    集成点:"javax.portlet.name" : a FQPN
    用途:
    例子:

    ===================

    com.liferay.portal.kernel.portlet.FriendlyURLMapper
    集成点:"javax.portlet.name" : a FQPN
    用途:
    例子:

    ===================

    com.liferay.portal.kernel.search.Indexer
    集成点:"javax.portlet.name" : a FQPN
    用途:
    例子:

    ===================

    com.liferay.portal.kernel.search.OpenSearch
    集成点:"javax.portlet.name" : a FQPN
    用途:
    例子:

    ===================

    com.liferay.portal.security.permission.PermissionPropagator
    集成点:"javax.portlet.name" : a FQPN
    用途:
    例子:

    ===================

    com.liferay.portal.kernel.pop.MessageListener
    集成点:"javax.portlet.name" : a FQPN
    用途:
    例子:

    ===================

    com.liferay.portal.kernel.lar.PortletDataHandler
    集成点:"javax.portlet.name" : a FQPN
    用途:
    例子:

    ===================

    com.liferay.portal.kernel.portlet.PortletLayoutListener
    集成点:"javax.portlet.name" : a FQPN
    用途:
    例子:

    ===================

    javax.portlet.PreferencesValidator
    集成点:"javax.portlet.name" : a FQPN
    用途:
    例子:

    ===================

    com.liferay.portal.kernel.lar.StagedModelDataHandler
    集成点:"javax.portlet.name" : a FQPN
    用途:
    例子:

    ===================

    com.liferay.portal.kernel.template.TemplateHandler
    集成点:"javax.portlet.name" : a FQPN
    用途:
    例子:

    ===================

    com.liferay.portal.kernel.trash.TrashHandler
    集成点:"javax.portlet.name" : a FQPN
    用途:
    例子:

    ===================

    com.liferay.portal.kernel.servlet.URLEncoder
    集成点:"javax.portlet.name" : a FQPN
    用途:
    例子:

    ===================

    com.liferay.portal.kernel.notifications.UserNotificationHandler
    集成点:"javax.portlet.name" : a FQPN
    用途:
    例子:

    ===================

    com.liferay.portal.kernel.webdav.WebDAVStorage
    集成点:"javax.portlet.name" : a FQPN
    用途:
    例子:

    ===================

    com.liferay.portal.kernel.workflow.WorkflowHandler
    集成点:"javax.portlet.name" : a FQPN
    用途:
    例子:

    ===================

    com.liferay.portal.kernel.xmlrpc.Method
    集成点:"javax.portlet.name" : a FQPN
    用途:
    例子:

    ===================

    com.liferay.portal.kernel.events.LifecycleAction
    集成点:
    用途:
    例子:

    ===================

    com.liferay.portal.kernel.search.IndexerPostProcessor
    集成点: "indexer.class.name" : a indexer or entity class name
    用途:
    例子:

    ===================

    com.liferay.portal.service.ServiceWrapper
    集成点:
    用途:
    例子:

    待续...

  • 相关阅读:
    字符编码及文件处理
    列表、元祖、字典及集合的内置方法
    数字类型、字符串及列表的内置方法
    流程控制(if while for)
    一些基本概念及数据类型
    编程语言的发展及变量
    python 入门基本知识
    叁拾贰(转)
    叁拾壹
    叁拾
  • 原文地址:https://www.cnblogs.com/starcrm/p/6062914.html
Copyright © 2011-2022 走看看