ï»??xml version="1.0" encoding="utf-8" standalone="yes"?> There are a number of distributions to choose from depending on your needs.
The The If installing to a directory that contains spaces, This section documents the manual installation of Pluto into Tomcat. It replaces the pluto:install goal, but requires that the built-in Maven 2 install goal ( Step 1: Step 2: Copy the following to
 //Servletåˆå§‹åŒ?br /> Pluto.PortalImpl.Servlet.init()
    // ServiceManageråˆå§‹åŒ?br />    ServiceManager.init()
       ConfigService.init() // é…ç½®æœåŠ¡
       LogService.init() // 日志æœåŠ¡
       FactoryManagerService.init() // 工厂½Ž¡ç†å™?/font>
       PortletDefinitionRegistryService.init() // Portlet定义注册�/font>
       PortletEntityRegistryService.init() // Portlet实体注册�/font>
       PageRegistryService.init() // Page注册�/font>
       //注,以上æœåŠ¡éƒ½è¯»å–åŒåçš„propertiesé…置文äšg.
    // åˆå§‹åŒ–Portlet容器, 容器实现¾cÕdœ¨ConfigService.properties䏿Œ‡å®?br />    PortletContainerFactory.getPortletContainer().init()
二ã€è¯·æ±‚å¤„ç†æµ½E?
 Pluto.PortalImpl.Servlet.doGet()
   1. 创å¾PortalEnvironment;
   2. 查找ActionWindow;
   2a. 如找到ActionWindow, åˆ™äØ“Action
   2b. 找ä¸åˆ°ActionWindow, åˆ™äØ“Render, è¯Õd–Page定义ã€?br />           RootFragment root = PageRegistry.getRootFragment();
   3. 处ç†å®Œæ¯•;
 // 处ç†Fragment, RootFragment与Pageregistry.xmlæ–‡äšgå…Œ™”, åŽè€…定义了™åµé¢çš„布局
   // æœåŠ¡å‰ç½®å¤„ç†ã€?br />   1. preService(request, response);
   // 包å«ä¸Žå½“å‰fragmentåŒåçš„jspæ–‡äšgåQŒå½“å‰äØ“RootFragmentã€?br />   2. RequestDispatcher rd = getServletConfig().getServletContext().
   // æœåŠ¡åŽç½®å¤„ç†
 // Pageregistry.xml
   〈fragment name="test" type="page"〉�// 对应PageFragment
       〈fragment name="row" type="row"〉�// 对应RowFragment
  // 上é¢çš„层‹Æ¡ç»“æž„å分清楚,其ä¸fragment与Fragmentçš„å¾cÕd¯¹åº”,上é¢çš„定义ä¸åŒ…括RootFragment,
  // é历åfragment, òq¶è°ƒç”¨å…¶æœåŠ¡æ–ÒŽ³•ã€?br />  while (childIterator.hasNext()) {
三ã€Portal处熋¹ç¨‹
 先æ¥çœ‹çœ‹Portletçš„åˆå§‹åŒ–, ä¸»è¦æ˜¯ä»Žé…置文äšgä¸è¯»å–Portlet定义ã€?br /> PortletFragment.init()
     // è¯Õd–Portlet的实体Id, 在pageregistry.xmlä¸ç”±portlet属性指å®?
     // è¯Õd–Portlet实体. portlet实体在portletentityregistry.xmlä¸å®šä¹?
     // portletentityregistry.xml
 // PortletæœåŠ¡
     //load protlet
       // 1.å–å¾—PortletDefinition, 从portletentityregistryä¸å®šä¹‰çš„applicationä¸è¯»å–portlet定义.
       // portlet.xml
             〈portlet-class〉org.apache.Pluto.portalImpl.portlet.TestPortlet�portlet-class�/font>
             〈init-param>
             〈supports�br />                 〈mime-type〉text/html�mime-type�br />                 〈portlet-mode〉VIEW�portlet-mode�br />                 〈portlet-mode〉EDIT�portlet-mode�br />                 〈portlet-mode〉HELP�portlet-mode�br />             �supports�/font>
             〈portlet-info�br />                   〈title〉Test Portlet #1�title�br />                   〈short-title〉Test #1�short-title�br />                   〈keywords〉Test,Testing�keywords�br />             �portlet-info>
             〈security-role-ref�br />                 〈role-name〉PlutoTestRole�role-name�br />                 〈role-link〉tomcat�role-link�br />             �security-role-ref�br />          �portlet�br />       〈portlet-app�/font>
       // 2.å–å¾—PortletInvoker
       // 3.执行loadæ“作
     // render Portlet
       // 1. å–å¾—PortletInvoker
       // 2. 执行renderæ“作ã€?br />       invoker.render(renderRequest, renderResponse);
     // 处ç†Title, support modes,
 // Portlet调用.
     // å–å¾—Portlet应用的dispatcher.
     // 讄¡½®å±žæ€? METHOD_ID为别对应load, renderå’Œactionã€?br />     servletRequest.setAttribute(Constants.METHOD_ID, methodID);
     // 调用PortletÂ
å››ã€Portlet处熋¹ç¨‹
 在Portlet应用的web.xmlä¸ï¼Œå®šä¹‰äº†PortletServlet为Portletçš„ServletåQŒå®ƒç”±dispatchæ–ÒŽ³•¾lŸä¸€˜q›è¡Œè¯äh±‚处ç†.
 PortletServlet.dispatch(...)
    // 讄¡½®portletConfig.
    Integer method_id = (Integer)request.getAttribute(Constants.METHOD_ID);
        // prepare container objects to run in this webModule
        portletClass.render(renderRequest,renderResponse);
        // prepare container objects to run in this webModule
        portletClass.processAction(actionRequest,actionResponse);
    è‡Ïx¤åQŒè¯·æ±‚就由portlet˜q›è¡Œå¤„ç†äº†ã€?/font>
从上é¢çš„‹¹ç¨‹å¯ä»¥çœ‹å‡ºåQŒPlutož®±æ˜¯ž®†è¯·æ±‚分‹z‘Öˆ°™åµé¢ä¸Šçš„å„个portletåQŒportletæ ÒŽ®method执行相应æ“作åQ?/font>
最åŽç”±Plutož®†å®ƒä»¬å¤„ç†çš„¾l“果按特定布局˜q›è¡Œæ˜„¡¤ºã€?/font>
Installing the Pluto 1.1 Binary Build
About Pluto Distributions
Building Pluto from Source
Maven 2 is utilized as the project management and build system for Pluto 1.1. Pluto currently provides Maven plugins which can be used to install the Pluto Portal, assemble portlet applications, deploy applications, and publish portlet applications to the Pluto Portal. Obtaining Pluto 1.1 Source Code
The Pluto project uses the Subversion version control system. If you're new to Subversion, you can check out the online book about Subversion. Note that we are currently using Subversion 1.3.x (there are separate versions of the book covering the different versions of Subversion). Web Access to Subversion To browse the Pluto 1.1 source code, you can use the ViewCVS web interface to Subversion. This is current at all times. Normal Subversion Access Anyone can check code out of Subversion anonymously. However, you need to specify a username and password in order to update the Subversion repository, and only Pluto committers have the permissions to do that. We run Subversion over standard HTTPS, so hopefully you won't have problems with intervening firewalls.
Check out from Subversion
Again, anyone can do this. To check out the latest distribution of Pluto 1.1 (trunk) to a directory called 'pluto' use this command: svn checkout https://svn.apache.org/repos/asf/portals/pluto/trunk/ pluto
To check out Pluto 1.1.1 source to the 'pluto' directory use this command: svn checkout https://svn.apache.org/repos/asf/portals/pluto/tags/pluto-1.1.1 pluto
Zipped up Pluto source distributions can also be downloaded from a distribution mirror. Building Pluto with Maven 2
If this is your first time building Pluto with Maven 2, edit ~/.m2/settings.xml
and add the <pluginGroups> element:
<settings>
...
<pluginGroups>
<pluginGroup>org.apache.pluto</pluginGroup>
</pluginGroups>
...
</settings>
org.apache.pluto
specified as a <pluginGroup>
, then the pluto:install
will fail.
<PLUTO-1.1-SRCHOME>
is the local directory where the Pluto 1.1 source distribution has been checked out or unzipped into. $> cd <PLUTO-1.1-SRCHOME>
$> mvn install
$> mvn pluto:install -DinstallDir=path/to/appserver
install
goal is a built in Maven 2 lifecycle which builds the project artifacts and installs them into the Maven repository. pluto:install
goal will take the resulting artifacts and properly deploy them within the configured Tomcat installation. Currently, the Pluto 1.1 install has been tested on Tomcat 5.5.9, 5.5.17 and 5.5.20. The Tomcat 5 archive can be found here. installDir
needs to be enclosed within quotes: C:\pluto> mvn pluto:install -DinstallDir="C:\Program Files\Apache Software Foundation\Tomcat 5.5"
Installing Pluto Manually
mvn install
) be run from <PLUTO-1.1-SRCHOME>
. $> cd <PLUTO-1.1-SRCHOME>
$> mvn install
<TOMCAT_HOME>/shared/lib
:
Step 3: Copy the following to <TOMCAT_HOME>/common/endorsed
:
Step 4: Copy the following to <TOMCAT_HOME>/conf/Catalina/localhost
:
Step 5: Copy the following to <TOMCAT_HOME>/webapps
:
Installing Pluto with a Windows EXE
The NSIS Installer is not yet complete, but we hope to have a fully functional one soon. Anyone is more than welcome to assist us in this process. Configuring Source-Built Pluto for Application Scope PortletSession Attributes
To be able to use application-scoped PortletSession
attributes in Pluto, modify the Connector element for port 8080 in <TOMCAT_HOME>/conf/server.xml
by adding the following attribute and value: emptySessionPath="true". Configuring User and Role in the Pluto Source Build
The Pluto Testsuite portlet application needs the role 'pluto
' to run the Security Mapping Test. So before starting tomcat, you should edit <TOMCAT_HOME>/conf/tomcat-users.xml
, add the role 'pluto
', and add a user in that role. The simplest way to do this is to edit add the 'pluto
' role to the 'tomcat
' user's record. Here is a sample tomcat-users.xml
file:
<?xml version="1.0" encoding="utf-8"?>
<tomcat-users>
<role rolename="pluto"/>
<role rolename="tomcat"/>
<role rolename="role1"/>
<user username="tomcat" password="tomcat" roles="tomcat,pluto"/>
<user username="role1" password="tomcat" roles="role1"/>
<user username="both" password="tomcat" roles="tomcat,role1"/>
</tomcat-users>
Starting the Portal
Now you are ready to use the Pluto Portal built from source. Start up tomcat by running startup.bat
(for windows) or startup.sh
(for *nix) in <TOMCAT_HOME>/bin
, and browse to http://localhost:8080/pluto/portal
. Login to Pluto using the user and password you just created in tomcat-users.xml
. If you added the 'pluto' role to the 'tomcat' user's record, you can login as 'tomcat/tomcat'. Plutoåˆå§‹åŒ–æµ½E?a title="æ°æ€¹…链接åQšPluto控制‹¹ç¨‹" >
一ã€åˆå§‹åŒ–‹¹ç¨‹
           执行PortletContainer.processPortletAction();
           é‡å®šå‘输å‡?
           root.service(servletRequest, servletResponse);
 Pluto.portalImpl.Aggregation.RootFragment.service()
                               getRequestDispatcher(BASE_ROOT+jspName);
      rd.include(request, response);
   3. postService(request, response);
 〈portal〉�// 对应RootFragment
   〈fragment name="navigation"
       class="org.apache.Pluto.portalImpl.aggregation.navigation.TabNavigation"�br />   �fragment�/font>
       〈navigation�br />           〈title〉Test�title�br />           〈description�..�description�br />       �navigation�/font>
           〈fragment name="col1" type="column"〉 �// 对应ColumnFragment
               〈fragment name="p1" type="portlet"〉 �// 对应PortletFragment
                   〈property name="portlet" value="3.1"/�br />               �fragment�br />               〈fragment name="p2" type="portlet"〉�// 对应PortletFragment
                   〈property name="portlet" value="4.1"/�br />               �fragment�br />           �fragment�br />       �fragment�br />   �fragment�br /> �portal�/font>
       PageFragment, RowFragment, ColumnFragmentå’ŒPortletFragmentåQŒé™¤äº†PortletFragment外,
       其它Fragment的处ç†å¤§è‡´ä¸Šæ˜¯ä¸€æ ïLš„åQ?br />  Iterator childIterator = fragment.getChildFragments().iterator();
      Fragment subfragment = (Fragment)childIterator.next();
      if (subfragment instanceof AbstractNavigationFragment)
      {
          subfragment.service(request, response);
          break;
      }
 }
     String portletEntityId = getInitParameters().getString("portlet");
     PortletEntity portletEntity = PortletEntityRegistry.getPortletEntity(...);
     〈portlet-entity-registry�br />       〈application id="3"〉�// 对应PortletApplicationEntity
          〈definition-id〉testsuite�definition-id�br />          〈portlet id="1"〉�// 对应PortletEntity
             〈definition-id〉testsuite.TestPortlet1�definition-id�br />             〈preferences�br />                 〈pref-name〉TestName4�pref-name�br />                 〈pref-value〉TestValue4�pref-value�br />                 〈read-only〉true�read-only�br />             �preferences�br />         �portlet>
      �application>
      〈application id="4"ã€?br />         〈definition-id>testsuiteã€?definition-idã€?br />         〈portlet id="1"ã€?br />             〈definition-id>testsuite.TestPortlet2ã€?definition-idã€?br />             〈preferencesã€?br />                 〈pref-name〉TestName4ã€?pref-nameã€?br />                 〈pref-value〉TestValue4ã€?pref-valueã€?br />                 〈read-only〉trueã€?read-onlyã€?br />             ã€?preferencesã€?br />         ã€?portletã€?br />      ã€?applicationã€?br />    ã€?portlet-entity-registryã€?br />     //è¦æ³¨æ„这里的applicationidå’Œportletid与pageregistryä¸çš„portletid的对应关¾p…R€?/font>
 PortletFragment.service()
     PortletContainer.portletLoad(...)
       PortletDefinition def = portletWindow.getPortletEntity().getPortletDefinition();
       〈portlet-app〉 �// 对应PortletApplicationDefinition
          〈portlet〉   �// 对应PortletDefinition
             〈description〉TestSuiteDescription�description�br />             〈portlet-name〉TestPortlet1�portlet-name�br />             〈display-name〉Test Portlet #1�display-name�/font>
                 〈name〉config�name�br />                 〈value�WEB-INF/testsuite-config.xml�value�br />             �init-param�/font>
       PortletInvoker invoker = PortletInvokerAccess.getPortletInvoker(def);
       invoker.load(renderRequest, renderResponse)
     PortletContainer.renderPortlet(...);
       PortletInvoker invoker = PortletInvokerAccess.getPortletInvoker(...);
 ProtletInvoker.invoke(...)
     ServletDefinition servletDefinition = portletDefinition.getServletDefinition();
     ServletContext servletContext = servletConfig.getServletContext();
     RequestDispatcher dispatcher = servletDefinition.getRequestDispatcher(servletContext);
     servletRequest.setAttribute(Constants.PORTLET_REQUEST, portletRequest);
     servletRequest.setAttribute(Constants.PORTLET_RESPONSE, portletResponse);
     dispatcher.include(servletRequest, servletResponse);
    request.setAttribute(org.apache.Pluto.Constants.PORTLET_CONFIG, portletConfig);
    if (method_id == Constants.METHOD_RENDER)
    {
        renderRequest = (RenderRequest)request.getAttribute(Constants.PORTLET_REQUEST);
        renderResponse = (RenderResponse)request.getAttribute(Constants.PORTLET_RESPONSE);
        prepareRenderRequest(renderRequest, request);
        prepareRenderResponse(renderResponse, request, response);
    }
    else if (method_id==org.apache.Pluto.Constants.METHOD_ACTION)
    {
        actionRequest = (ActionRequest)request.getAttribute(Constants.PORTLET_REQUEST);
        actionResponse = (ActionResponse)request.getAttribute(Constants.PORTLET_RESPONSE);
        prepareActionRequest(actionRequest, request);
        prepareActionResponse(actionResponse, request, response);
    }
    else if (method_id == org.apache.Pluto.Constants.METHOD_NOOP)
    {
        //nothing to do
    }
    //æ³? portletClasså³äØ“portlet的具体实现类ã€?/font>
å›?是Portal的基本体¾pÈ»“构图。Portal Web Application处ç†å®¢æˆ·çš„请求,从客æˆïLš„å½“å‰ ™åµä¸æå–出portletsåQŒç„¶åŽè°ƒç”¨portlet容器æ¥èŽ·å¾—æ¯ä¸€ä¸ªportlet的内å®V€‚Portal通过 Portlet容器的Invoker APIæ¥è®¿é—®portlet容器。这些API是portlet容器的主è¦è°ƒç”¨æŽ¥å£ï¼Œ 它们为Portalæä¾›äº†ä¸€äº›åŸºäºŽè¯·æ±‚çš„æ–ÒŽ³•æ¥è°ƒç”¨portlet。容器的使用者(å³PortalåQŒè¯‘è€?æ³?/i>åQ‰å¿…™åÕd®žçްportlet容器的Container Provider SPIåQˆService Provider InterfaceåQ‰å›žè°ƒæŽ¥å£ï¼Œæ¥äØ“portlet容器æä¾›ä¸ŽPortal相关的信æ¯ã€‚最åŽï¼Œportlet容器é€?˜q‡Portlet API调用所有的portletsã€?
å›?åQšä¸€ä¸ªé›†æˆäº†Pluto的简å•Portal
Portlet容器是portletsçš„è¿è¡Œæ—¶çŽ¯å¢ƒåQŒä¹Ÿæ˜¯æ¯ä¸€ä¸ªPortalçš„æ ¸å¿ƒç»„ä»¶ã€‚Portlet容器需è¦èŽ· å–æœ‰å…³Portal本èín的一些信æ¯ï¼Œ˜q˜å¿…™å»é‡ç”¨Portal的一些基本代ç ã€‚å› æ¤ï¼ŒPortlet容器å¯ä»¥ ä¿è¯è‡ªå·±ä¸Žå…¶å®ƒçš„Portal¾l„äšg之间是完全分开的。也ž®±æ˜¯è¯ß_¼Œä½ å¯ä»¥æŠŠä¸€ä¸ªç‹¬ç«‹çš„Portlet容器 æ’å…¥åˆîC“Q何一个Portalä¸åŽ»åQŒåªè¦å®ƒå¯ä»¥æ»¡èƒöPortletå®¹å™¨çš„è¦æ±‚,比如实现了所有的SPIã€?
Portlet容器的Invoker APIåQˆä¹Ÿè¢«ç§°ä¸ø™¿›å…¥ç‚¹åQ‰æ˜¯Portlet容器的主è¦è°ƒç”¨æŽ¥å£ã€‚这些APIåŒ?å«Portlet容器的生命周期控制方法(init()åQŒdestroy()åQ‰å’ŒåŸÞZºŽè¯äh±‚的调用方æ³?åQˆinitPage()åQŒperformTitle()åQŒportletService()½{‰ç‰åQ‰ã€‚由于Portlet容器最¾lˆæ˜¯ 去调用一个portletåQŒæ•…˜q™äº›æ–ÒŽ³•çš„ç¾åå’ŒPortlet API的主è¦portlet接å£å¾ˆç±»ä¼û|¼Œé™¤äº†ä¸€ä¸?™å»é¢å¤–ä¼ å…¥çš„portlet ID。Portlet容器å¯ä»¥é€šè¿‡˜q™ä¸ªé¢å¤–ä¼ å…¥çš„portlet ID傿•°æ¥å†³å®šè°ƒç”?哪一个portletã€?
除了å¯ä»¥ä½¿ç”¨Invoker APIæ¥è°ƒç”¨Portlet容器外,Portal˜q˜å¿…™åÕd®žçްPortlet容器定义的SPIã€?å› æ¤åQŒå‚考实现引入了“容器æœåŠ¡â€çš„æ¦‚念åQšå®¹å™¨æœåŠ¡ç”¨æ¥å®šä¹‰ä¸€äº›èƒ½å¤Ÿåœ¨å®¹å™¨ä¸æ³¨å†Œçš„坿’的组ä»Óž¼Œ ˜q™äº›¾l„äšgè¦ä¹ˆæä¾›ä¸€äº›åŸºæœ¬çš„功能åQŒè¦ä¹ˆå¯¹å®¹å™¨˜q›è¡Œæ‰©å±•。Plutoå‚考实现定义了下题q™äº›å†…å¾çš?容器æœåŠ¡åQˆå‰å››ä¸ªæ˜¯è¿è¡ŒPortlet容器所必须实现的,而第五个则是å¯é€‰çš„åQ‰ï¼š
ä¸¥æ ¼çš„è¯´åQŒPortlet Object ModelåQˆPortlet对象模型åQ‰ä¹Ÿæ˜¯ä¸€ä¸ªSPIåQŒä½†ä¸Žå…¶å®ƒçš„SPI相比åQ?它处在一个特ŒDŠçš„ä½ç½®ä¸Šã€‚å› æ¤æˆ‘ä»¬ä¸æŠŠå®ƒçœ‹æˆæ˜¯å®¹å™¨æœåŠ¡çš„ä¸€éƒ¨åˆ†åQŒå› ä¸ºå®ƒå¤„ç†æ‰€æœ‰çš„portlet 对象åQŒåƈ包å«äº†ä¸€äº›æØœæ‚的接å£ã€?
å›?åQšPortlet容器的体¾pÈ»“æž?/b>
JSR 168规范和Web Service for Remote PortletsåQˆWSRPåQ‰æ ‡å‡†æœ‰é«˜åº¦çš„一致性。这ä¸?ä¸ªåŒæ—¶å‡ºçŽ°çš„æ ‡å‡†éƒ½å‘布了开放æºç 的实现åQŒå®ƒä»¬çš„实现都完æˆäº†åœ¨ç›¸åº”的规范ä¸å®šä¹‰çš„æ‰€æœ‰å¿…è¦?åŠŸèƒ½ã€‚è¿™ä¸¤ä¸ªæ ‡å‡†éƒ½æŠŠèƒ½å¾ˆå¥½çš„äº’ç›¸åä½œä½œäØ“å®ƒä»¬å…±åŒçš„ç›®æ ‡ã€‚å› æ¤ï¼ŒWSRP portletsåœ?portlet容噍䏿—¢å¯ä»¥ä½œäؓ消费者è¿è¡Œï¼Œä¹Ÿå¯ä»¥ä½œä¸ºç”Ÿäº§è€…è¿è¡Œã€?
Pluto™å¹ç›®å¿…须支æŒåœ¨ä¸€ä¸ªPortalä¸è¿è¡Œå¤šä¸ªportletå®¹å™¨ã€‚å› æ¤ï¼ŒPluto Portlet容器å¯ä»¥ 被多‹Æ¡åˆå§‹åŒ–。更é‡è¦çš„æ˜¯åQŒå®ƒå¯ä»¥ä»¥ä¸åŒçš„æ–¹å¼˜q行åQŒæ¯ä¸ªportlet容器都ä‹É用一个ä¸åŒçš„SPI 实现ã€?