From do-not-reply at jboss.org Wed Mar 20 22:26:50 2013 Content-Type: multipart/mixed; boundary="===============0725143513055394243==" MIME-Version: 1.0 From: do-not-reply at jboss.org To: gatein-commits at lists.jboss.org Subject: [gatein-commits] gatein SVN: r9218 - in epp/docs/JPP/trunk/Reference_Guide/en-US/modules: Advanced and 2 other directories. Date: Wed, 20 Mar 2013 22:26:49 -0400 Message-ID: <201303210226.r2L2Qnji028130@svn01.web.mwc.hst.phx2.redhat.com> --===============0725143513055394243== Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Author: jaredmorgs Date: 2013-03-20 22:26:49 -0400 (Wed, 20 Mar 2013) New Revision: 9218 Modified: epp/docs/JPP/trunk/Reference_Guide/en-US/modules/Advanced/Foundations.xml epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment.xml epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment/DataI= mportStrategy.xml epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment/Defau= ltPortalConfiguration.xml epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment/Defau= ltPortalNavigationConfiguration.xml epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment/Defau= ltPortalPermissionConfiguration.xml epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment/Inter= nationalizationConfiguration.xml epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment/Javas= criptInterApplicationCommunication.xml epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment/Local= izationConfiguration.xml epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment/Navig= ationController.xml epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment/Porta= lLifecycle.xml epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment/RTLFr= amework.xml epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment/Skinn= ing.xml epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment/XMLRe= sourceBundles.xml epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortletDevelopment/Glob= al_Portlet.xml epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortletDevelopment/Port= letBridge.xml epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortletDevelopment/Stan= dard.xml epp/docs/JPP/trunk/Reference_Guide/en-US/modules/ServerIntegration.xml Log: Made statements in all migrated sections for tracking purposes. Al= l Portal and Portlet Development topics are migrated over to the Developers= Guide. Modified: epp/docs/JPP/trunk/Reference_Guide/en-US/modules/Advanced/Foundat= ions.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- epp/docs/JPP/trunk/Reference_Guide/en-US/modules/Advanced/Foundations.x= ml 2013-03-21 02:18:56 UTC (rev 9217) +++ epp/docs/JPP/trunk/Reference_Guide/en-US/modules/Advanced/Foundations.x= ml 2013-03-21 02:26:49 UTC (rev 9218) @@ -5,15 +5,3359 @@ ]> The eXo Kernel - - - - - - - - - - - + MOVED to Development Guide - The_eXo_Kernel.xml +
+ eXo Kernel + +JBoss Portal Platform is built as a set of services on top of a dependency= injection kernel. The kernel provides configuration, life-cycle handling, = component scopes and some core services. + + + The portal kernel and the JCR used in JBoss Portal Platform use the Inversion of Control (IoC) system to control service instantiation. This method is also known as &= apos;dependency injection'. + + + In this system, services are not responsible for the instantiation of th= e components on which they depend. It prevents objects creating the instanc= es of any objects referenced. This task is delegated to the container. The = below image illustrates this: + +
+ Inversion of Control + + + + + + + + +
+ + There are two ways to inject a dependency : + + + Using a constructor: + + public ServiceA(Servic= eB serviceB) + + Using setter methods: + + public void setService= B(ServiceB serviceB) + + When a client service can not be stored in the container then the servic= e locator pattern is used: + + public ServiceA(){ +this.serviceB =3DContainer.getSInstance().getService(ServiceB.class); +} + + The container package is responsible of building a hierarchy of containe= rs. Each service will then be registered in one container or the other acco= rding to the XML configuration file it is defined in. It is important to un= derstand that there can be several PortalContainer instances that all are c= hildren of the RootContainer. + + + The behavior of the hierarchy is similar to a class loader one, hence wh= en you will lookup a service that depends on another one, the container wil= l look for it in the current container and if it cannot be found, then it w= ill look in the parent container. That way you can load all the reusable bu= siness logic components in the same container (here the RootContainer) and = differentiate the service implementation from one portal instance to the ot= her by just loading different service implementations in two sibling Portal= Containers. + + + Therefore, if you look at the Portal Container as a service repository f= or all the business logic in a portal instance, then you understand why sev= eral PortalContainers allows you to manage several portals (each one deploy= ed as a single war) in the same server by just changing XML configuration f= iles. + + + The default configuration XML files are packaged in the service jar. The= re are three configuration.xml files, one for each container type. In that = XML file, we define the list of services and their init parameters that wil= l be loaded in the corresponding container. + + + Service components exist in two scopes. The first scope is represented b= y the RootContainer. It contains services that exist ind= ependently of any portal, and can be accessed by all portals. + + + The second scope, the PortalContainer, is portal-spec= ific. Each portal exists in an instance of the PortalContainer. This scope contains services that are common for a set of portals, = and services which should not be shared by all portals. + + + + + RootContainer: This is a base container. This container plays an impor= tant role during startup, but you should not use it directly. + + + + + PortalContainer: Created at the startup of the portal web application = (in the init() method of the PortalController servlet) + + + + +
+ Portal Containers + + + + + + + + +
+ +
+ + As there can be several portal container instances per JVM. it is import= ant to be able to configure the loaded services per instance. Therefore all= the default configuration files located in the service impl jar can be ove= rridden from the portal war. + + + Whenever a specific service is looked up through the PortalCont= ainer, and the service is not available, the lookup is delegated = further up to the RootContainer. + + +JBoss Portal Platform can have default instances of a certain component in= the RootContainer, and portal specific instances in som= e or all PortalContainers, that override the default ins= tance. + + + Whenever your portal application has to be integrated more closely with = eXo services, these services can be looked up through the PortalCo= ntainer. + + + + Only officially documented services should be accessed this way, and us= ed according to documentation, as most of the services are an implementatio= n detail of eXo, and subject to change without notice. + + +
+ Kernel configuration namespace + + To be effective, the namespace URI http://www.exoplaform.org/xml/n= s/kernel_1_2.xsd must be target namespace of the XML configuration fi= le. + + <configuration xmln= s:xsi=3D"http://www.w3.org/2001/XMLSchema-instance" = + xsi:schemaLocation=3D"http://www.exoplaform.org/xml/ns/ker= nel_1_2.xsd http://www.exoplaform.org/xml/ns/kernel_1_2.xsd" + xmlns=3D"http://www.exoplaform.org/xml/ns/kernel_1_2.xsd&q= uot;> + + +... +</configuration> + + + Any values in the configuration files can be created thanks to variabl= es since the eXo kernel resolves them, for example the following configurat= ion will be well interpreted: + + <configuration +xmlns:xsi=3D"http://www.w3.org/2001/XMLSchema-instance" +xsi:schemaLocation=3D"http://www.exoplaform.org/xml/ns/kernel_1_2.xsd= http://www.exoplaform.org/xml/ns/kernel_1_2.xsd" +xmlns=3D"http://www.exoplaform.org/xml/ns/kernel_1_2.xsd"> + +<import>${db.configuration.path}/db.xml</import> +<import>${java.io.tmpdir}/bindfile.xml</import> +<import>simple.xml</import> + +</configuration> + + The variables that are supported, are System properties and variables = that are specific to your portal container, see next sections for more deta= ils. + + +
+
+
+ Configuration Retrieval + + The container performs the following steps for configuration retrieval, = depending on the container type. + + + The container is initialized by looking into different locations. This c= ontainer is used by portal applications. Configurations are overloaded in t= he following lookup sequence: + + + + + Services default RootContainer configurations from JAR = files /conf/configuration.xml. + + + + + Services default PortalContainer configurations from JA= R files /conf/portal/configuration.xml. + + + + + Web applications configurations from WAR files /WEB-INF/conf= /configuration.xml + + + + + + The search looks for a configuration file in each JAR/WAR available fro= m the classpath using the current thread context classloader. During the se= arch these configurations are added to a set. If the service was configured= previously and the current JAR contains a new configuration of that servic= e the latest (from the current JAR/WAR) will replace the previous one. The = last one will be applied to the service during the services start phase. + + + NEEDINFO - FILE PATHS - the file before was configuration.xml,= but I'm pretty sure all this is defined in standalone.xml now, correc= t? + + + Take care to have no dependencies between configurations from JAR files= (/conf/portal/configuration.xml and /conf/c= onfiguration.xml) since we have no way to know in advance the lo= ading order of those configurations. In other words, if you want to overloa= d some configuration located in the file /conf/portal/configurati= on.xml of a given JAR file, you must not do it from the file /conf/portal/configuration.xml of another JAR file but fr= om another configuration file loaded after configurations from JAR files /conf/portal/configuration.xml. + + + + After the processing of all configurations available in system, the cont= ainer will initialize it and start each service in order of the dependency = injection (DI). + + + The user/developer should be careful when configuring the same service i= n different configuration files. It's recommended to configure a servi= ce in its own JAR only. Or, in case of a portal configuration, strictly rec= onfigure the services in portal WAR files or in an external configuration. + + + There are services that can be (or should be) configured more than one t= ime. This depends on business logic of the service. A service may initializ= e the same resource (shared with other services) or may add a particular ob= ject to a set of objects (shared with other services too). In the first cas= e, it's critical who will be the last, i.e. whose configuration will b= e used. In the second case, it's no matter who is the first and who is= the last (if the parameter objects are independent). + + + In case of problems with service configuration, it's important to k= now from which JAR/WAR it comes. For that purpose, the JVM system property = org.exoplatform.container.configuration.debug can be use= d. + + java -Dorg.exoplatform.container.configuration.debug .= .. + + If the property is enabled, the container configuration manager will log= the configuration adding process at INFO level. + + ...... + Add configuration jar:file:/D:/Projects/eXo/dev/exo-working/exo-tomcat/= lib/exo.kernel.container-trunk.jar!/conf/portal/configuration.xml + Add configuration jar:file:/D:/Projects/eXo/dev/exo-working/exo-tomcat/= lib/exo.kernel.component.cache-trunk.jar!/conf/portal/configuration.xml + Add configuration jndi:/localhost/portal/WEB-INF/conf/configuration.xml + import jndi:/localhost/portal/WEB-INF/conf/common/common-configura= tion.xml + import jndi:/localhost/portal/WEB-INF/conf/database/database-confi= guration.xml + import jndi:/localhost/portal/WEB-INF/conf/ecm/jcr-component-plugi= ns-configuration.xml + import jndi:/localhost/portal/WEB-INF/conf/jcr/jcr-configuration.x= ml = + ...... + + The effective configuration of the StandaloneContainer, RootContainer an= d/or PortalContainer can be known thanks to the method getConfigu= rationXML() that is exposed through JMX at the container's = level. This method will give you the effective configuration in XML format = that has been really interpreted by the kernel. This could be helpful to un= derstand how a given component or plug-in has been initialized. + +
+
+ Advanced concepts for the <emphasis>PortalContainers</emphasis>= + + Since eXo JCR 1.12, we added a set of new features that have been design= ed to extend portal applications such as JBoss Portal Platform. + +
+ Add new configuration files from a WAR file + + A ServletContextListener called org.exoplatform.c= ontainer.web.PortalContainerConfigOwner has been added in order to = notify the application that a given web application provides some configura= tion to the portal container, and this configuration file is the file WEB-INF/conf/configuration.xml available in the web applica= tion itself. + + + If your war file contains some configuration to add to the Porta= lContainer simply add the following lines in your web.xml= file. + + <?xml version=3D&qu= ot;1.0" encoding=3D"ISO-8859-1" ?> +<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Appli= cation 2.3//EN" + "http://java.sun.com/dtd/web-app_2_3.dtd"> +<web-app> +... + <!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --> + <!-- LISTENER = --> + <!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --> + <listener> + <listener-class>org.exoplatform.container.web.PortalContainerCon= figOwner</listener-class> + </listener> +... +</web-app> +
+
+ Creating your <emphasis>PortalContainers</emphasis> from a WA= R file + + A ServletContextListener called org.exoplatform.c= ontainer.web.PortalContainerCreator has been added in order to crea= te the current portal containers that have been registered. We assume that = all the web applications have already been loaded before calling Por= talContainerCreator.contextInitialized. + + + + + In JBoss Portal Platform, the PortalContainerCreator i= s already managed by the file starter.war/ear. + + + + +
+
+ Defining a <emphasis>PortalContainer</emphasis> with its depe= ndencies and its settings + + Now we can define precisely a portal container and its dependencies and= settings thanks to the PortalContainerDefinition that curre= ntly contains the name of the portal container, the name of the rest contex= t, the name of the realm, the web application dependencies ordered by loadi= ng priority (i.e. the first dependency must be loaded at first and so on..)= and the settings. + + + To be able to define a PortalContainerDefinition, we nee= d to ensure first of all that a PortalContainerConfig has be= en defined at the RootContainer level, see an example below: + + <component> + <!-- The full qualified name of the PortalContainerConfig --> + <type>org.exoplatform.container.definition.PortalContainerConfig= </type> + <init-params> + <!-- The name of the default portal container --> + <value-param> + <name>default.portal.container</name> + <value>myPortal</value> + </value-param> + <!-- The name of the default rest ServletContext --> + <value-param> + <name>default.rest.context</name> + <value>myRest</value> + </value-param> + <!-- The name of the default realm --> + <value-param> + <name>default.realm.name</name> + <value>my-exo-domain</value> + </value-param> + <!-- Indicates whether the unregistered webapps have to be ignored= --> + <value-param> + <name>ignore.unregistered.webapp</name> + <value>true</value> + </value-param> + <!-- The default portal container definition --> + <!-- It cans be used to avoid duplicating configuration --> + <object-param> + <name>default.portal.definition</name> + <object type=3D"org.exoplatform.container.definition.Porta= lContainerDefinition"> + <!-- All the dependencies of the portal container ordered by = loading priority --> + <field name=3D"dependencies"> + <collection type=3D"java.util.ArrayList"> + <value> + <string>foo</string> + </value> + <value> + <string>foo2</string> + </value> + <value> + <string>foo3</string> + </value> + </collection> + </field> = + <!-- A map of settings tied to the default portal container -= -> + <field name=3D"settings"> + <map type=3D"java.util.HashMap"> + <entry> + <key> + <string>foo5</string> + </key> + <value> + <string>value</string> + </value> + </entry> + <entry> + <key> + <string>string</string> + </key> + <value> + <string>value0</string> + </value> + </entry> + <entry> + <key> + <string>int</string> + </key> + <value> + <int>100</int> + </value> + </entry> + </map> + </field> + <!-- The path to the external properties file --> + <field name=3D"externalSettingsPath"> + <string>classpath:/org/exoplatform/container/definition/= default-settings.properties</string> + </field> + </object> + </object-param> + </init-params> + </component> + + Descriptions of the fields of <envar>PortalContainerConfig<= /envar> + + + + default.portal.container (*) + The name of the default portal container. This field= is optional. + + + default.rest.context (*) + The name of the default rest ServletContext. This field is optional. + + + default.realm.name (*) + The name of the default realm. This field is optiona= l. + + + ignore.unregistered.webapp (*) + Indicates whether the unregistered webapps have to b= e ignored. If a webapp has not been registered as a dependency of any porta= l container, the application will use the value of this parameter to know w= hat to do: + + + If it is set to false, this webapp will be = considered by default as a dependency of all the portal containers. + + + + + If it is set to true, this webapp won'= t be considered by default as a dependency of any portal container, it will= be simply ignored. + + + This field is optional and by default this= parameter is set to false. + + + default.portal.definition + The definition of the default portal container. This= field is optional. The expected type is org.exoplatform.container. = definition.PortalContainerDefinition that is described below. Allow= the parameters defined in this default PortalContainerDefinition will be the default values. + + + +
+ + + All the value of the parameters marked with a (*) can be defined thank= s to System properties like any values in configuration files but also than= ks to variables loaded by the PropertyConfigurator. Fo= r example in JBoss Portal Platform by default, it would be all the variable= s defined in the file configuration.properties. + + + + A new PortalContainerDefinition can be defined at the RootContainer level thanks to an external plug-in, see an exam= ple below: + + <external-compone= nt-plugins> + <!-- The full qualified name of the PortalContainerConfig --> + <target-component>org.exoplatform.container.definition.PortalCon= tainerConfig</target-component> + <component-plugin> + <!-- The name of the plugin --> + <name>Add PortalContainer Definitions</name> + <!-- The name of the method to call on the PortalContainerConfig = in order to register the PortalContainerDefinitions --> + <set-method>registerPlugin</set-method> + <!-- The full qualified name of the PortalContainerDefinitionPlug= in --> + <type>org.exoplatform.container.definition.PortalContainerDefi= nitionPlugin</type> + <init-params> + <object-param> + <name>portal</name> + <object type=3D"org.exoplatform.container.definition.Por= talContainerDefinition"> + <!-- The name of the portal container --> + <field name=3D"name"> + <string>myPortal</string> + </field> + <!-- The name of the context name of the rest web applicati= on --> + <field name=3D"restContextName"> + <string>myRest</string> + </field> + <!-- The name of the realm --> + <field name=3D"realmName"> + <string>my-domain</string> + </field> + <!-- All the dependencies of the portal container ordered b= y loading priority --> + <field name=3D"dependencies"> + <collection type=3D"java.util.ArrayList"> + <value> + <string>foo</string> + </value> + <value> + <string>foo2</string> + </value> + <value> + <string>foo3</string> + </value> + </collection> + </field> + <!-- A map of settings tied to the portal container --> + <field name=3D"settings"> + <map type=3D"java.util.HashMap"> + <entry> + <key> + <string>foo</string> + </key> + <value> + <string>value</string> + </value> + </entry> + <entry> + <key> + <string>int</string> + </key> + <value> + <int>10</int> + </value> + </entry> + <entry> + <key> + <string>long</string> + </key> + <value> + <long>10</long> + </value> + </entry> + <entry> + <key> + <string>double</string> + </key> + <value> + <double>10</double> + </value> + </entry> + <entry> + <key> + <string>boolean</string> + </key> + <value> + <boolean>true</boolean> + </value> + </entry> = + </map> + </field> = + <!-- The path to the external properties file --> + <field name=3D"externalSettingsPath"> + <string>classpath:/org/exoplatform/container/definitio= n/settings.properties</string> + </field> + </object> + </object-param> + </init-params> + </component-plugin> + </external-component-plugins> + + Descriptions of the fields of a PortalContainerDefinition w= hen it is used to define a new portal container + + + + name (*) + The name of the portal container. This field is mand= atory . + + + restContextName (*) + The name of the context name of the rest web applica= tion. This field is optional. The default value will be defined at the PortalContainerConfig level. + + + realmName (*) + The name of the realm. This field is optional. The d= efault value will be defined at the PortalContainerConfig le= vel. + + + dependencies + All the dependencies of the portal container ordered= by loading priority. This field is optional. The default value will be def= ined at the PortalContainerConfig level. The dependencies ar= e in fact the list of the context names of the web applications from which = the portal container depends. This field is optional. The dependency order = is really crucial since it will be interpreted the same way by several comp= onents of the platform. All those components, will consider the 1st element= in the list less important than the second element and so on. It is curren= tly used to: + + + Know the loading order of all the dependencies. + + + + + If we have several PortalContainerConfigOwner + + + The ServletContext of all the PortalCon= tainerConfigOwner will be unified, if we use the unified Ser= vletContext (PortalContainer.getPortalContext()) to get a resource, it will try to get the resource in the Servlet= Context of the most important PortalContainerConfigOwner (i.e. last in the dependency list) and if it cans find it, it will try= with the second most important PortalContainerConfigOwner a= nd so on. + + + + + The ClassLoader of all the PortalContai= nerConfigOwner will be unified, if we use the unified ClassL= oader (PortalContainer.getPortalClassLoader())= to get a resource, it will try to get the resource in the ClassLoad= er of the most important PortalContainerConfigOwner = (i.e. last in the dependency list) and if it can find it, it will try with = the second most important PortalContainerConfigOwner and so = on. + + + + + + + + + + settings + A java.util.Map of internal parameter= s that we would like to tie the portal container. Those parameters could ha= ve any type of value. This field is optional. If some internal settings are= defined at the PortalContainerConfig level, the two maps of= settings will be merged. If a setting with the same name is defined in bot= h maps, it will keep the value defined at the PortalContainerDefinit= ion level. + + + externalSettingsPath + The path of the external properties file to load as = default settings to the portal container. This field is optional. If some e= xternal settings are defined at the PortalContainerConfig le= vel, the two maps of settings will be merged. If a setting with the same na= me is defined in both maps, it will keep the value defined at the Po= rtalContainerDefinition level. The external properties files can be= either of type "properties" or of type "xml". The path= will be interpreted as follows: + + + The path doesn't contain any prefix of type "classpath= :", "jar:" or "file:", we assume that the file cou= ld be externalized so we apply the following rules: = + + + + A file exists at ${exo-conf-dir}/portal/${portalCon= tainerName}/${externalSettingsPath}, we will load this file. + + + + + No file exists at the previous path, we then assume that the = path can be interpreted by the ConfigurationManager. + + + + + + + + + The path contains a prefix, we then assume that the path can be = interpreted by the ConfigurationManager. + + + + + + +
+ + Descriptions of the fields of a <envar>PortalContainerDefin= ition</envar> when it is used to define the default portal container + + + + name (*) + The name of the portal container. This field is opti= onal. The default portal name will be: + + + If this field is not empty, then the default value will be the v= alue of this field. + + + + + If this field is empty and the value of the parameter = default.portal.container is not empty, then the default value wi= ll be the value of the parameter. + + + + + If this field and the parameter default.portal.contain= er are both empty, the default value will be "por= tal". + + + + + + restContextName (*) + The name of the context name of the rest web applica= tion. This field is optional. The default value will be: + + + If this field is not empty, then the default value will be the v= alue of this field. + + + + + If this field is empty and the value of the parameter = default.rest.context is not empty, then the default value will b= e the value of the parameter. + + + + + If this field and the parameter default.rest.context are both empty, the default value will be "rest&qu= ot;. + + + + + + realmName (*) + The name of the realm. This field is optional. The d= efault value will be: + + + If this field is not empty, then the default value will be the v= alue of this field. + + + + + If this field is empty and the value of the parameter = default.realm.name is not empty, then the default value will be = the value of the parameter. + + + + + If this field and the parameter default.realm.name are both empty, the default value will be "exo-domai= n". + + + + + + dependencies + All the dependencies of the portal container ordered= by loading priority. This field is optional. If this field has a non empty= value, it will be the default list of dependencies. + + + settings + A java.util.Map of internal parameter= s that we would like to tie the default portal container. Those parameters = could have any type of value. This field is optional. + + + externalSettingsPath + The path of the external properties file to load as = default settings to the default portal container. This field is optional. T= he external properties files can be either of type "properties" o= r of type "xml". The path will be interpreted as follows: + + + The path doesn't contain any prefix of type "classpath= :", "jar:" or "file:", we assume that the file cou= ld be externalized so we apply the following rules: = + + + + A file exists at ${exo-conf-dir}/portal/${externalS= ettingsPath}, we will load this file. + + + + + No file exists at the previous path, we then assume that the = path can be interpreted by the ConfigurationManager. + + + + + + + + + The path contains a prefix, we then assume that the path can be = interpreted by the ConfigurationManager. + + + + + + +
+ + + All the value of the parameters marked with a (*) can be defined thank= s to System properties like any values in configuration files but also than= ks to variables loaded by the PropertyConfigurator. Fo= r example in JBoss Portal Platform by default, it would be all the variable= s defined in the file configuration.properties. + + + + Internal and external settings are both optional, but if we give a non = empty value for both the application will merge the settings. If the same s= etting name exists in both settings, we apply the following rules: + + + + + The value of the external setting is null, we ig= nore the value. + + + + + The value of the external setting is not null an= d the value of the internal setting is null, the final= value will be the external setting value that is of type String. + + + + + Both values are not null, we will have to convert the = external setting value into the target type which is the type of the intern= al setting value, thanks to the static method valueOf(String), the following sub-rules are then applied: + + + + + The method cannot be found, the final value will be the external se= tting value that is of type String. + + + + + The method can be found and the external setting value is an empty = String, we ignore the external setting value. + + + + + The method can be found and the external setting value is not an em= pty String but the method call fails, we ignore the external= setting value. + + + + + The method can be found and the external setting value is not an em= pty String and the method call succeeds, the final value wil= l be the external setting value that is of type of the internal setting val= ue. + + + + + +
+
+ <envar>PortalContainer</envar> settings + + We can inject the value of the portal container settings into the porta= l container configuration files thanks to the variables which name start wi= th "portal.container.", so to get the value = of a setting called "foo", just use the foll= owing syntax ${portal.container.foo}. You can also use= internal variables, such as: + + + Definition of the internal variables + + + + portal.container.name + Gives the name of the current portal container. + + + portal.container.rest + Gives the context name of the rest web application o= f the current portal container. + + + portal.container.realm + Gives the realm name of the current portal container= . + + + +
+ + You can find below an example of how to use the variables: + + <configuration xmln= s:xsi=3D"http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLoc= ation=3D"http://www.exoplaform.org/xml/ns/kernel_1_2.xsd http://www.ex= oplaform.org/xml/ns/kernel_1_2.xsd" + xmlns=3D"http://www.exoplaform.org/xml/ns/kernel_1_2.xsd"> + <component> + <type>org.exoplatform.container.TestPortalContainer$MyComponent&= lt;/type> + <init-params> + <!-- The name of the portal container --> + <value-param> + <name>portal</name> + <value>${portal.container.name}</value> + </value-param> + <!-- The name of the rest ServletContext --> + <value-param> + <name>rest</name> + <value>${portal.container.rest}</value> + </value-param> + <!-- The name of the realm --> + <value-param> + <name>realm</name> + <value>${portal.container.realm}</value> + </value-param> + <value-param> + <name>foo</name> + <value>${portal.container.foo}</value> + </value-param> + <value-param> + <name>before foo after</name> + <value>before ${portal.container.foo} after</value> + </value-param> + </init-params> + </component> +</configuration> + + In the properties file corresponding to the external settings, you can = reuse variables previously defined (in the external settings or in the inte= rnal settings) to create a new variable. In this case, the prefix "portal.container." is not needed, see an example bel= ow: = +my-var1=3Dvalue 1 +my-var2=3Dvalue 2 +complex-value=3D${my-var1}-${my-var2} + + + + In the external and internal settings, you can also use create variable= s based on value of System parameters. The System parameters can either be = defined at launch time or thanks to the PropertyConfigurator= (see next section for more details). See an example below: + + temp-dir=3D${java.io.tmpdir}${file.separator}my-temp= + + However, for the internal settings, you can use System parameters only = to define settings of type java.lang.String. + + + It cans be also very useful to define a generic variable in the setting= s of the default portal container, the value of this variable will change a= ccording to the current portal container. See below an example: = +my-generic-var=3Dvalue of the portal container "${nam= e}" + + + + If this variable is defined at the default portal container level, the = value of this variable for a portal container called "foo&qu= ot; will be value of the portal container "foo&qu= ot;. + +
+
+ Adding dynamically settings and/or dependencies to a <envar>P= ortalContainer</envar> + + It is possible to use component-plugin elements in order= to dynamically change a PortalContainerDefinition. In the example below, w= e add the dependency foo to the default portal container and= to the portal containers called foo1 and foo2: + + <external-component= -plugins> + <!-- The full qualified name of the PortalContainerConfig --> + <target-component>org.exoplatform.container.definition.PortalConta= inerConfig</target-component> + <component-plugin> + <!-- The name of the plugin --> + <name>Change PortalContainer Definitions</name> + <!-- The name of the method to call on the PortalContainerConfig in= order to register the changes on the PortalContainerDefinitions --> + <set-method>registerChangePlugin</set-method> + <!-- The full qualified name of the PortalContainerDefinitionChange= Plugin --> + <type>org.exoplatform.container.definition.PortalContainerDefini= tionChangePlugin</type> + <init-params> + <value-param> + <name>apply.default</name> + <value>true</value> + </value-param> + <values-param> + <name>apply.specific</name> + <value>foo1</value> + <value>foo2</value> + </values-param> = + <object-param> + <name>change</name> + <object type=3D"org.exoplatform.container.definition.Porta= lContainerDefinitionChange$AddDependencies"> + <!-- The list of name of the dependencies to add --> + <field name=3D"dependencies"> + <collection type=3D"java.util.ArrayList"> + <value> + <string>foo</string> + </value> + </collection> + </field> + </object> + </object-param> = + </init-params> + </component-plugin> +</external-component-plugins> + + Descriptions of the fields of a <envar>PortalContainerDefin= itionChangePlugin</envar> + + + + apply.all (*) + Indicates whether the changes have to be applied to = all the portal containers or not. The default value of this field is false. This field is a ValueParam and is not mandat= ory. + + + apply.default (*) + Indicates whether the changes have to be applied to = the default portal container or not. The default value of this field is false. This field is a ValueParam and is not man= datory. + + + apply.specific (*) + A set of specific portal container names to which we= want to apply the changes. This field is a ValuesParam and = is not mandatory. + + + + Rest of the expected parameters + + The rest of the expected parameters are Objec= tParam of type PortalContainerDefinitionChange. Thos= e parameters are in fact the list of changes that we want to apply to one o= r several portal containers. If the list of changes is empty, the component= plug-in will be ignored. The supported implementations of PortalContainerD= efinitionChange are described later in this section. + + + +
+ + + All the value of the parameters marked with a (*) can be defined thank= s to System properties like any values in configuration files but also than= ks to variables loaded by the PropertyConfigurator. Fo= r example in JBoss Portal Platform by default, it would be all the variable= s defined in the file configuration.properties. + + + + To identify the portal containers to which the changes have to be appli= ed, we use the following algorithm: + + + + + The parameter apply.all has been set to true. The corresponding changes will be applied to all the portal containe= rs. The other parameters will be ignored. + + + + + The parameter apply.default has been set to tru= e and the parameter apply.specific is null. The corresponding changes will be applied to the default portal cont= ainer only. + + + + + The parameter apply.default has been set to tru= e and the parameter apply.specific is not nul= l. The corresponding changes will be applied to the default portal = container and the given list of specific portal containers. + + + + + The parameter apply.default has been set to fal= se or has not been set and the parameter apply.specific is null. The corresponding changes will be applied to th= e default portal container only. + + + + + The parameter apply.default has been set to fal= se or has not been set and the parameter apply.specific is not null. The corresponding changes will be applied t= o the given list of specific portal containers. + + + +
+ The existing implementations of <envar>PortalContainerDefin= itionChange</envar> + + The modifications that can be applied to a PortalContainerDefin= ition must be a class of type PortalContainerDefinitionChang= e. The product proposes out of the box some implementations that we= describe in the next sub sections. + +
+ + <envar>AddDependencies</envar> + + + This modification adds a list of dependencies at the end of the list = of dependencies defined into the PortalContainerDefinition. = The full qualified name is org.exoplatform.container.definition.P= ortalContainerDefinitionChange$AddDependencies. + + + Descriptions of the fields of an <envar>AddDependencies= </envar> + + + + dependencies + A list of String correspond= ing to the list of name of the dependencies to add. If the value of this fi= eld is empty, the change will be ignored. + + + +
+ + See an example below, that will add foo at the end of = the dependency list of the default portal container: + + <external-compo= nent-plugins> + <!-- The full qualified name of the PortalContainerConfig --> + <target-component>org.exoplatform.container.definition.PortalConta= inerConfig</target-component> + <component-plugin> + <!-- The name of the plugin --> + <name>Change PortalContainer Definitions</name> + <!-- The name of the method to call on the PortalContainerConfig in= order to register the changes on the PortalContainerDefinitions --> + <set-method>registerChangePlugin</set-method> + <!-- The full qualified name of the PortalContainerDefinitionChange= Plugin --> + <type>org.exoplatform.container.definition.PortalContainerDefini= tionChangePlugin</type> + <init-params> + <value-param> + <name>apply.default</name> + <value>true</value> + </value-param> + <object-param> + <name>change</name> + <object type=3D"org.exoplatform.container.definition.Porta= lContainerDefinitionChange$AddDependencies"> + <!-- The list of name of the dependencies to add --> + <field name=3D"dependencies"> + <collection type=3D"java.util.ArrayList"> + <value> + <string>foo</string> + </value> + </collection> + </field> + </object> + </object-param> = + </init-params> + </component-plugin> +</external-component-plugins> +
+
+ + <envar>AddDependenciesBefore</envar> + + + This modification adds a list of dependencies before a given target d= ependency defined into the list of dependencies of the PortalContain= erDefinition. The full qualified name is org.exoplatform.= container.definition.PortalContainerDefinitionChange$AddDependenciesBefore<= /emphasis>. + + + Descriptions of the fields of an <envar>AddDependencies= Before</envar> + + + + dependencies + A list of String correspond= ing to the list of name of the dependencies to add. If the value of this fi= eld is empty, the change will be ignored. + + + target + The name of the dependency before which we would= like to add the new dependencies. If this field is null or = the target dependency cannot be found in the list of dependencies defined i= nto the PortalContainerDefinition, the new dependencies will= be added in first position to the list. + + + +
+ + See an example below, that will add foo before = foo2 in the dependency list of the default portal container: + + <external-compo= nent-plugins> + <!-- The full qualified name of the PortalContainerConfig --> + <target-component>org.exoplatform.container.definition.PortalConta= inerConfig</target-component> + <component-plugin> + <!-- The name of the plugin --> + <name>Change PortalContainer Definitions</name> + <!-- The name of the method to call on the PortalContainerConfig in= order to register the changes on the PortalContainerDefinitions --> + <set-method>registerChangePlugin</set-method> + <!-- The full qualified name of the PortalContainerDefinitionChange= Plugin --> + <type>org.exoplatform.container.definition.PortalContainerDefini= tionChangePlugin</type> + <init-params> + <value-param> + <name>apply.default</name> + <value>true</value> + </value-param> + <object-param> + <name>change</name> + <object type=3D"org.exoplatform.container.definition.Porta= lContainerDefinitionChange$AddDependenciesBefore"> + <!-- The list of name of the dependencies to add --> + <field name=3D"dependencies"> + <collection type=3D"java.util.ArrayList"> + <value> + <string>foo</string> + </value> + </collection> + </field> + <!-- The name of the target dependency --> + <field name=3D"target"> + <string>foo2</string> + </field> + </object> + </object-param> = + </init-params> + </component-plugin> +</external-component-plugins> +
+
+ + <envar>AddDependenciesAfter</envar> + + + This modification adds a list of dependencies before a given target d= ependency defined into the list of dependencies of the PortalContain= erDefinition. The full qualified name is org.exoplatform.= container.definition.PortalContainerDefinitionChange$AddDependenciesAfter. + + + Descriptions of the fields of an <envar>AddDependencies= After</envar> + + + + dependencies + A list of String correspond= ing to the list of name of the dependencies to add. If the value of this fi= eld is empty, the change will be ignored. + + + target + The name of the dependency after which we would = like to add the new dependencies. If this field is null or t= he target dependency cannot be found in the list of dependencies defined in= to the PortalContainerDefinition, the new dependencies will = be added in last position to the list. + + + +
+ + See an example below, that will add foo after f= oo2 in the dependency list of the default portal container: + + <external-compo= nent-plugins> + <!-- The full qualified name of the PortalContainerConfig --> + <target-component>org.exoplatform.container.definition.PortalConta= inerConfig</target-component> + <component-plugin> + <!-- The name of the plugin --> + <name>Change PortalContainer Definitions</name> + <!-- The name of the method to call on the PortalContainerConfig in= order to register the changes on the PortalContainerDefinitions --> + <set-method>registerChangePlugin</set-method> + <!-- The full qualified name of the PortalContainerDefinitionChange= Plugin --> + <type>org.exoplatform.container.definition.PortalContainerDefini= tionChangePlugin</type> + <init-params> + <value-param> + <name>apply.default</name> + <value>true</value> + </value-param> + <object-param> + <name>change</name> + <object type=3D"org.exoplatform.container.definition.Porta= lContainerDefinitionChange$AddDependenciesAfter"> + <!-- The list of name of the dependencies to add --> + <field name=3D"dependencies"> + <collection type=3D"java.util.ArrayList"> + <value> + <string>foo</string> + </value> + </collection> + </field> + <!-- The name of the target dependency --> + <field name=3D"target"> + <string>foo2</string> + </field> + </object> + </object-param> = + </init-params> + </component-plugin> +</external-component-plugins> +
+
+ + <envar>AddSettings</envar> + + + This modification adds new settings to a PortalContainerDefini= tion. The full qualified name is org.exoplatform.containe= r.definition.PortalContainerDefinitionChange$AddSettings. + + + Descriptions of the fields of an <envar>AddSettings</en= var> + + + + settings + A map of <String, Object> corresponding to the settings to add. If the value of this field is em= pty, the change will be ignored. + + + +
+ + See an example below, that will add the settings string and stringX to the settings of the default portal containe= r: + + <external-compo= nent-plugins> + <!-- The full qualified name of the PortalContainerConfig --> + <target-component>org.exoplatform.container.definition.PortalConta= inerConfig</target-component> + <component-plugin> + <!-- The name of the plugin --> + <name>Change PortalContainer Definitions</name> + <!-- The name of the method to call on the PortalContainerConfig in= order to register the changes on the PortalContainerDefinitions --> + <set-method>registerChangePlugin</set-method> + <!-- The full qualified name of the PortalContainerDefinitionChange= Plugin --> + <type>org.exoplatform.container.definition.PortalContainerDefini= tionChangePlugin</type> + <init-params> + <value-param> + <name>apply.default</name> + <value>true</value> + </value-param> + <object-param> + <name>change</name> + <object type=3D"org.exoplatform.container.definition.Porta= lContainerDefinitionChange$AddSettings"> + <!-- The settings to add to the to the portal containers --&g= t; + <field name=3D"settings"> + <map type=3D"java.util.HashMap"> + <entry> + <key> + <string>string</string> + </key> + <value> + <string>value1</string> + </value> + </entry> + <entry> + <key> + <string>stringX</string> + </key> + <value> + <string>value1</string> + </value> + </entry> + </map> + </field> + </object> + </object-param> = + </init-params> + </component-plugin> +</external-component-plugins> +
+
+
+
+ Disable dynamically a portal container + + It is possible to use component-plugin elements in order= to dynamically disable one or several portal containers. In the example be= low, we disable the portal container named foo: + + <external-component= -plugins> + <!-- The full qualified name of the PortalContainerConfig --> + <target-component>org.exoplatform.container.definition.PortalConta= inerConfig</target-component> + <component-plugin> + <!-- The name of the plugin --> + <name>Disable a PortalContainer</name> + <!-- The name of the method to call on the PortalContainerConfig in= order to register the changes on the PortalContainerDefinitions --> + <set-method>registerDisablePlugin</set-method> + <!-- The full qualified name of the PortalContainerDefinitionDisabl= ePlugin --> + <type>org.exoplatform.container.definition.PortalContainerDefini= tionDisablePlugin</type> + <init-params> + <!-- The list of the name of the portal containers to disable --&= gt; + <values-param> + <name>names</name> + <value>foo</value> + </values-param> + </init-params> + </component-plugin> +</external-component-plugins> + + + + names (*) + The list of the name of the portal containers to dis= able. + + + +
+ + + All the value of the parameters marked with a (*) can be defined thank= s to System properties like any values in configuration files but also than= ks to variables loaded by the PropertyConfigurator. Fo= r example in JBoss Portal Platform by default, it would be all the variable= s defined in the file configuration.properties. + + + + To prevent any accesses to a web application corresponding to Po= rtalContainer that has been disabled, you need to make sure that th= e following Http Filter (or a sub class of it) has been added to your web.x= ml in first position as below: + + <filter> + <filter-name>PortalContainerFilter</filter-name> + <filter-class>org.exoplatform.container.web.PortalContainerFilter&= lt;/filter-class> +</filter> = + +<filter-mapping> + <filter-name>PortalContainerFilter</filter-name> + <url-pattern>/*</url-pattern> +</filter-mapping> + + + It is only possible to disable a portal container when at least one Po= rtalContainerDefinition has been registered. + + +
+
+
+ Runtime configuration profiles + + The kernel configuration is able to handle configuration profiles at run= time (as opposed to packaging time). + +
+ Profiles activation + + An active profile list is obtained during the boot of the root containe= r and is composed of the system property exo.profiles = sliced according the "," delimiter and also a server specific pro= file value (tomcat for tomcat, jboss for jboss, etc...). + + # runs JBoss Portal Platform on Tomcat with the prof= iles tomcat and foo +sh JBoss Portal Platform.sh -Dexo.profiles=3Dfoo + +# runs JBoss Portal Platform on JBoss with the profiles jboss, foo and bar +sh run.sh -Dexo.profiles=3Dfoo,bar +
+
+ Profiles configuration + + Profiles are configured in the configuration files of the eXo kernel. + +
+ Profiles definition + + Profile activation occurs at XML to configuration object unmarshalling= time. It is based on an "profile" attribute that is present on s= ome of the XML element of the configuration files. To enable this, the kern= el configuration schema has been upgraded to kernel_1_2.xsd. The configurat= ion is based on the following rules: + + + + + Any kernel element with the no profiles attribu= te will create a configuration object + + + + + Any kernel element having a profiles attribute = containing at least one of the active profiles will create a configuration = object + + + + + Any kernel element having a profiles attribute = matching none of the active profile will not create a configuration object + + + + + Resolution of duplicates (such as two components with same type) is = left up to the kernel + + + +
+
+ Profiles capable configuration elements + + A <configuration> element is profiles-capab= le when it carries a <profiles> element. + +
+ <component> element + + The <component> element declares a component when activated. It= will shadow any element with the same key declared before in the same conf= iguration file: + + <component> + <key>Component</key> + <type>Component</type> +</component> + +<component profiles=3D"foo"> + <key>Component</key> + <type>FooComponent</type> +</component> +
+
+ <component-plugin> element + + The <component-plugin> element is used to dynamically extend th= e configuration of a given component. Thanks to the profiles the <compon= ent-plugin> elements can be enabled or disabled: + + <external-compo= nent-plugins> + <target-component>Component</target-component> + <component-plugin profiles=3D"foo"> + <name>foo</name> + <set-method>addPlugin</set-method> + <type>type</type> + <init-params> + <value-param> + <name>param</name> + <value>empty</value> + </value-param> + </init-params> + </component-plugin> +</external-component-plugins> +
+
+ <import> element + + The <import> element imports a referenced configuration file wh= en activated: + + <import>empt= y</import> +<import profiles=3D"foo">foo</import> +<import profiles=3D"bar">bar</import> +
+
+ <init-params> element + + The <init-params> element configures the parameter argument of = the construction of a component service: + + <component> + <key>Component</key> + <type>ComponentImpl</type> + <init-params> + <value-param> + <name>param</name> + <value>empty</value> + </value-param> + <value-param profiles=3D"foo"> + <name>param</name> + <value>foo</value> + </value-param> + <value-param profiles=3D"bar"> + <name>param</name> + <value>bar</value> + </value-param> + </init-params> +</component> +
+
+ <value-collection> element + + The <value-collection> element configures one of the value of c= ollection data: + + <object type=3D= "org.exoplatform.container.configuration.ConfigParam"> + <field name=3D"role"> + <collection type=3D"java.util.ArrayList"> + <value><string>manager</string></value> + <value profiles=3D"foo"><string>foo_manager<= ;/string></value> + <value profiles=3D"foo,bar"><string>foo_bar_ma= nager</string></value> + </collection> + </field> +</object> +
+
+ <field-configuration> element + + The <field-configuration> element configures the field of an ob= ject: + + <object-param&g= t; + <name>test.configuration</name> + <object type=3D"org.exoplatform.container.configuration.ConfigPa= ram"> + <field name=3D"role"> + <collection type=3D"java.util.ArrayList"> + <value><string>manager</string></value> + </collection> + </field> + <field name=3D"role" profiles=3D"foo,bar"> + <collection type=3D"java.util.ArrayList"> + <value><string>foo_bar_manager</string></valu= e> + </collection> + </field> + <field name=3D"role" profiles=3D"foo"> + <collection type=3D"java.util.ArrayList"> + <value><string>foo_manager</string></value> + </collection> + </field> + </object> +</object-param> +
+
+
+
+
+ Component request life cycle +
+ Component request life cycle contract + + The component request life cycle is an interface that defines a contrac= t for a component for being involved into a request: + + public interface Com= ponentRequestLifecycle +{ + /** + * Start a request. + * @param container the related container + */ + void startRequest(ExoContainer container); + = + /** + * Ends a request. + * @param container the related container + */ + void endRequest(ExoContainer container); +} + + The container passed is the container to which the component is related= . This contract is often used to setup a thread local based context that wi= ll be demarcated by a request. + + + For instance in the portal context, a component request life cycle is t= riggered for user requests. Another example is the initial data import in G= ateIn that demarcates using callbacks made to that interface. + +
+
+ Request life cycle + + The RequestLifeCycle class has several statics methods t= hat are used to schedule the component request life cycle of components. It= s main responsibility is to perform scheduling while respecting the constra= int to execute the request life cycle of a component only once even if it c= an be scheduled several times. + +
+ Scheduling a component request life cycle + RequestLifeCycle.b= egin(component); +try +{ + // Do something +} +finally +{ + RequestLifeCycle.end(); +} +
+
+ Scheduling a container request life cycle + + Scheduling a container triggers the component request life cycle of al= l the components that implement the interface ComponentRequestLifeCy= cle. If one of the component has already been scheduled before and = then that component will not be scheduled again. When the local value is tr= ue, then the looked components will be those of the container, when it is f= alse then the scheduler will also look at the components in the ancestor co= ntainers. + + RequestLifeCycle.b= egin(container, local); +try +{ + // Do something +} +finally +{ + RequestLifeCycle.end(); +} +
+
+ When request life cycle is triggered +
+ Portal request life cycle + + Each portal request triggers the life cycle of the associated portal = container. + +
+
+ JMX request Life Cycle + + When a JMX bean is invoked, the request life cycle of the container t= o which it belongs it scheduled. Indeed JMX is an entry point of the system= that may need component to have a request life cycle triggered. + +
+
+
+
+
+ Configuring Services + + The eXo Kernel uses dependency injection to create services based = on configuration.xml configuration files. The location= of the configuration files determines if services are placed into the RootContainer scope, or into the PortalContainer scope. + + + When creating a service, you also should declare its existence to = the Container. This can be done by creat= ing a simple configuration file. + + + Copy the following code to a configuration.xml file and save this file in a /conf subdirectory of = your service base folder. The container looks for a /conf/configu= ration.xml file in each jar-file. + + + All configuration.xml files located at conf/configuration.xml in the classpath (any directory, or a= ny jar in the classpath) will have their services configured in the RootContainer scope. + + + All configuration.xml files located at conf/portal/configuration.xml in the classpath will have th= eir services configured at the PortalContainer scope. + + + Additionally, portal extensions= can use configuration information stored in JPP_DIS= T/gatein/gatein.ear/portal.war/WEB-INF/conf/configuration.xml= , and will also have their services configured in the P= ortalContainer scope. + + + When eXo kernel reads a configuration, it loads the file from the = kernel jar using the classloader and does not use an internet connection to= resolve the file. + + + + Portal extensions are descr= ibed later in this document. + + +
+ Configuration syntax +
+ Components + + A service component is defined in configuration.= xml by using a <component> element. + + + Only one piece of information is required when defining a = service; the service implementation class. This is specified using <type= > + + + Every component has a <key> that identifies it. If n= ot explicitly set, a key defaults to the value of <type>. If a key ca= n be loaded as a class, a class object is used as a key, otherwise a string= is used. + + + The usual approach is to specify an interface as a key. + + + + The configuration found inside the jar file is considered = as the default configuration. If you want to override this default configur= ation you can do it in different places outside the jar. When the container= finds several configurations for the same service, the configuration which= is found later replaces completely the one found previously. Let's ca= ll this the configuration override mechanism. + + All custom configuration is made in the webapps/po= rtal/WEB-INF/conf/configuration.xml file. Use <component> = elements to contain the configuration information. The <key> element = defines the interface, and the <type> tag defines the implementation= . While the <key> tag is not mandatory, it can lead to a small perfor= mance improvement. + + <!-- Portlet cont= ainer hooks --> + <component> + <key>org.exoplatform.services.portletcontainer.persistence.Portl= etPreferencesPersister</key> + <type>org.exoplatform.services.portal.impl.PortletPreferencesPer= sisterImpl</type> + </component> + + Register plug-ins that can act as listeners or external pl= ug-in to bundle some plug-in classes in other jar modules. The usual exampl= e is the hibernate service to which we can add hbm mapping files even if th= ose are deployed in an other maven artifact. + + <external-compone= nt-plugins> + <target-component>org.exoplatform.services.database.HibernateServi= ce</target-component> + <component-plugin> = + <name>add.hibernate.mapping</name> + <set-method>addPlugin</set-method> + <type>org.exoplatform.services.database.impl.AddHibernateMapping= Plugin</type> + <init-params> + <values-param> + <name>hibernate.mapping</name> + <value>org/exoplatform/services/portal/impl/PortalConfigData= .hbm.xml</value> + <value>org/exoplatform/services/portal/impl/PageData.hbm.xml= </value> + <value>org/exoplatform/services/portal/impl/NodeNavigationDa= ta.hbm.xml</value> + </values-param> = + </init-params> + </component-plugin> +</external-component-plugins> + + In that sample we target the HibernateService and we will = call its addPlugin() method with an argument of the type AddHibernateMappin= gPlugin. That object will first have been filled with the init parameters. + + + Therefore, it is possible to define services that will be = able to receive plug-ins without implementing any framework interface. + + + Another example of use is the case of listeners as in the = following code where a listener is added to the OrganisationService and wil= l be called each time a new user is created: + + <external-compone= nt-plugins> + <target-component>org.exoplatform.services.organization.Organizati= onService</target-component> + <component-plugin> + <name>portal.new.user.event.listener</name> + <set-method>addListenerPlugin</set-method> + <type>org.exoplatform.services.portal.impl.PortalUserEventListen= erImpl</type> + <description>this listener create the portal configuration for t= he new user</description> + <init-params> + <object-param> + <name>configuration</name> + <description>description</description> + <object type=3D"org.exoplatform.services.portal.impl.NewPo= rtalConfig"> + <field name=3D"predefinedUser"> + <collection type=3D"java.util.HashSet"> + <value><string>admin</string></value> + <value><string>exo</string></value> + <value><string>company</string></value&= gt; + <value><string>community</string></valu= e> + <value><string>portal</string></value&g= t; + <value><string>exotest</string></value&= gt; + </collection> + </field> + <field name=3D"templateUser"><string>temp= late</string></field> + <field name=3D"templateLocation"><string>= war:/conf/users</string></field> + </object> + </object-param> + </init-params> + </component-plugin> +... + + In the previous XML configuration, we refer the organizati= on service and we will call its method addListenerPlugin with an object of = type PortalUserEventListenerImpl. Each time a new user will be created (apa= rt the predefined ones in the list above) methods of the PortalUserEventLis= tenerImpl will be called by the service. + + + As you can see, there are several types of init parameters= , from a simple value param which binds a key with a value to a more comple= x object mapping that fills a JavaBean with the info defined in the XML. + + + Many other examples exist such as for the Scheduler Servic= e where you can add a job with a simple XML configuration or the JCR Servic= e where you can add a NodeType from your own configuration.xml file. + +
+ RootContainer + + As PortalContainer depends on the RootContainer, we wi= ll start by looking into this one. + + + The retrieval sequence in short: + + + + + Services default RootContainer configurations from JAR files /conf/configuration.xml + + + + + External RootContainer = configuration, to be found at exo-tomcat/exo-conf/configuration.x= ml + + + + + + Naturally you always have to replace ex= o-tomcat by your own folder name. + + + + The RootContainer creates a jav= a HashTable which contains key-value pairs for the s= ervices. The qualified interface name of each service is used as key for th= e hashtable. Hopefully you still remember that the <key> tag of the configuration file contains the interface name? The v= alue of each hashtable pair is an object that contains the service configur= ation (yes, this means the whole structure between the <compo= nent> tags of your configuration.xml fi= le). + + + The RootContainer runs over all= jar files you find in exo-tomcat/lib and looks if the= re is a configuration file at /conf/configuration.xml,= the services configured in this file are added to the hashtable. That way = - at the end of this process - the default configurations for all services = are stored in the hashtable. + + + + What happens if the same service - recognized by t= he same qualified interface name - is configured in different jars? As the = service only can exist one time the configuration of the jar found later ov= errides the previous configuration. You know that the loading order of the jars is unpredictable you must not depend on this. + + + + If you wish to provide your own configurations for one= or several services, you can do it in a general configuration file that ha= s to be placed at exo-tomcat/exo-conf/configuration.xml. Do not search for such a file on your computer - you won't find one= , because this option is not used in the default installation. Here again t= he same rule applies: The posterior configuration replaces the pr= evious one. + + + The further configuration retrieval depends on the con= tainer type. + +
+
+ PortalContainer + + The PortalContainer takes the hashtable filled by the = RootContainer and continues to look in some more places. Here you get the o= pportunity to replace RootContainer configurations by those which are speci= fic to your portal. Again, the configurations are overridden whenever neces= sary. + + + In short PortalContainer configurations are retrieved = in the following lookup sequence : + + + + + Take over the configurations of the RootContai= ner + + + + + Default PortalContainer configurations from al= l JAR files (folder /conf/portal/configuration.xml) + + + + + Web application configurations from the portal= .war file - or the portal web app (folder /W= EB-INF/conf/configuration.xml) + + + + + External configuration for services of a named= portal, it will be found at exo-tomcat/exo-conf/portal/$portal_n= ame/configuration.xml (as of Portal 2.5) + + + + + You see, here the /conf/portal/configuration= .xml file of each jar enters the game, they are searched at firs= t. Next, there is nearly always a configuration.xml in the portal.war file = (or in the portal webapp folder), you find this file at /WEB-INF/= conf/configuration.xml. If you open it, you will find a lot of i= mport statements that point to other configuration files in the same portal= .war (or portal webapp). + + + Multiple Portals Be= aware that you might set up several different portals ("admin", = "mexico", etc.), and each of these portals will use a different P= ortalContainer. And each of these PortalContainers can be configured separa= tely. As of JBoss Portal Platform &VY; you also will be able to provide con= figurations from outside the jars and wars or webapps. Put a configuration = file in exo-tomcat/exo-conf/portal/$portal_name/configuration.xml= where $portal_name is the name of the po= rtal you want to configure for . But normally you only have one portal whic= h is called "portal" so you use exo-tomcat/exo-conf/por= tal/portal/configuration.xml. + + + + As of JBoss Portal Platform &VY; you can override = the external configuration location with the system property exo.= conf.dir. If the property exists its value will be used as path = to the eXo configuration directory, that means this is an alternative to exo-tomcat/exo-conf. Just put this property in the comma= nd line: java -Dexo.conf.dir=3D/path/to/exo/conf or us= e eXo.bat or eXo.sh. In this particular use case, you have no need to use a= ny prefixes in your configuration file to import other files. For example, = if your configuration file is exo-tomcat/exo-conf/portal/PORTAL_N= AME/configuration.xml and you want to import the configuration f= ile exo-tomcat/exo-conf/portal/PORTAL_NAME/mySubConfDir/myConfig.= xml, you can do it by adding <import>mySubConfDi= r/myConfig.xml</import> to your configuration file. + + + + + Under JBoss app= lication server exo-conf will be looked up in director= y described by JBoss System property jboss.server.config.url. If the property is not found or empty exo-jboss/exo-conf<= /emphasis> will be asked (since kernel 2.0.4). + + +
+
+ External Plug-ins + + The eXo Kernel supports non-component objects that can= be configured, instantiated, and injected into registered components using= method calls. This 'plugin' method allows p= ortal extensions to add additional configurations to core services. + + + An external plug-in is defined by using the &= lt;external-component-plugin> wrapper element which contains o= ne or more <component-plugin> definitions. + + + The <external-component-plugin> element uses <target-component> to specify a ta= rget service component that will receive injected objects. + + + Every <component-plugin> defi= nes an implementation type, and a method on the target component to use for= injection (<set-method>). + + + A plug-in implementation class has to implement the org.exoplatform.container.component. ComponentPlugin<= /emphasis> interface. + + + In the following example the PortalContainerD= efinitionPlugin implements the ComponentPlugin: + + + + The <target-component> defines the service for which the plug-in is defined. The configu= ration is injected by the container using a method that is defined in <set-method>. The method has exactly on= e argument of the type org.exoplatform.services.cms.categories.impl.Taxonom= yPlugin: + + + + + addTaxonomyPlugin(org.exoplatform.services.cms= .categories.impl.TaxonomyPlugin plugin) + + + + + The content of <init-params= > corresponds to the structure of the TaxonomyPlugin object. + + + + You can configure the component CategoriesService = using the addTaxonomyPlugin as often as you wish, you can also call addTaxo= nomyPlugin in different configuration files. The method addTaxonomyPlugin i= s then called several times, everything else depends on the implementation = of the method. + + +
+
+ Service instantiation + + As you have already learned the services are all singl= etons, so that the container creates only one single instance of each conta= iner. The services are created by calling the constructors (called constructor injection). If there are only zero-arguments const= ructors (Foo public Foo(){}) there are no problems to be expec= ted. That's easy. + + + But now look at OrganizationServiceImpl.java + + + This JDBC implementation of BaseOrganizationService in= terface has only one constructor: + + public Organizat= ionServiceImpl(ListenerService listenerService, DatabaseService dbService);= + + You see this service depends on two other services. In= order to be able to call this constructor the container first needs a ListenerService and a DatabaseService. Therefore these services must be instantiated before BaseO= rganizationService, because BaseOrganizationService<= /classname> depends on them. + + + For this purpose the container first looks at the cons= tructors of all services and creates a matrix of service dependencies in or= der to call the services in a proper order. If for any reason there are int= erdependencies or circular dependencies you will get a java Exce= ption. In this way the dependencies are injected by t= he container. + + + + What happens if one service has more than one cons= tructor? The container always tries first to use the constructor with a max= imum of arguments, if this is not possible the container continues step by = step with constructors that have less arguments until arriving at the zero-= argument constructor (if there is one). + + +
+
+ Service Access + + As you want to follow the principle of Inversion of Control, you must= not access the service directly. You need a Container to access the service. + + + With this command you get your current container: + + + + + ExoContainer myContain= er =3D ExoContainerContext.getCurrentContainer(); + + + + + Whenever you need one of the services that you have co= nfigured use the method: + + + + + myContainer.getCompone= ntInstance(class) + + + + + In our case: + + + + + ArticleStatsService st= atsService =3D (ArticleStatsService) myContainer.getComponentInstance(Artic= leStatsService.class); + + + + + Recapitulation: + + package com.lave= rdad.common; + +import org.exoplatform.container.ExoContainer; +import org.exoplatform.container.ExoContainerContext; +import com.laverdad.services.*; + +public class Statistics { + + public int makeStatistics(String articleText) { + ExoContainer myContainer =3D ExoContainerContext.getCurrentContainer(); + ArticleStatsService statsService =3D (ArticleStatsService) + myContainer.getComponentInstance(ArticleStatsService.class); = + int numberOfSentences =3D statsService.calcSentences(articleText); + return numberOfSentences; + } + = + public static void main( String args[]) { + Statistics stats =3D new Statistics(); + String newText =3D "This is a normal text. The method only counts = the number of periods. " + + "You can implement your own implementation with a more exact cou= nting. " + + "Let`s make a last sentence."; + System.out.println("Number of sentences: " + stats.makeStatist= ics(newText)); + } +} +
+
+ Includes, and special URLs + + It is possible to divide the configuration.x= ml file into many smaller files, which are then included into th= e main configuration file. + + + The included files must be valid xml files; they canno= t be fragments of text. + + + Below is an example configuration.xml that 'outsources' its content into several files: + + + + Comment #1: This line is being used to ref= erence another configuration file. The war: URL schema indicat= es that the following path is to be resolved relative to the current PortalContainer's servlet context resource path, starting= with WEB-INF as a root. + + + + The current PortalContainer is = really a newly created PortalContainer, as war: URLs only make sense for PortalContainer scoped con= figuration. + + + + Through the extension mechanism the servlet context us= ed for resource loading is a unified servlet contex= t (this is explained in a later section). + + + To have an 'include' path resolved relative = to current classpath (context classloader), use a 'jar:' URL schema. + +
+
+ Special variables + + Configuration files may contain a special variable reference ${container.name.suffix= }. This variable resolves to the name of the current portal cont= ainer, prefixed by underscore (_). + + + This facilitates reuse of configuration files in situa= tions where portal-specific unique names need to be assigned to some resour= ces; JNDI names, Database/DataSource names and JCR repository names, for ex= ample. + + + This variable is only defined when there is a current = PortalContainer available and is only available for PortalContainer scoped services. + + + A good example of this is the = HibernateService: + + +
+
+
+ <init-params> configuration element + <init-params> is a configuration element that is essen= tially a map of key-value pairs, where key is always a String, and value= can be any type that can be described using the kernel XML conf= iguration. + + + Service components that form the JBoss Portal Platform inf= rastructure use <init-params> elements to configure themselves. A com= ponent can have one instance of <init-params> injected at most. + + + If the service component's constructor takes <init= -params> as any of the parameters it will automatically be injected at c= omponent instantiation time. + + + The XML configuration for a service component that expects= an <init-params> element must have an <init-params> element pr= esent, however this element can be left empty. + + + Below is an example of how the kernel XML configuration sy= ntax looks when creating <init-params> instances: + + + + An <init-params> element description begins with an = <init-params> element. + + + It can have zero or more children elements, each of which = is one of the following: + + + + + <value-param> + + + + + <values-param> + + + + + <properties-param> + + + + + <object-param> + + + + + Each of these child elements takes a <name> that ser= ves as a map entry key, and an optional <description>. It also takes = a type-specific value specification. + + + The value specification for the <properties-param> d= efines one or more <property> elements, each of which specifies two s= trings; a property name and a property value. This is evident in the two pr= evious examples. + + + Each <properties-params> defines one java.u= til.Properties instance. + + + <properties-param> Hibernate Example + <component> + <key>org.exoplatform.services.database.HibernateService</key&= gt; + <type>org.exoplatform.services.database.impl.HibernateServiceImp= l</type> + <init-params> + <properties-param> + <name>hibernate.properties</name> + <description>Default Hibernate Service</description> + <property name=3D"hibernate.show_sql" value=3D"f= alse"/> + <property name=3D"hibernate.cglib.use_reflection_optimizer= " value=3D"true"/> + <property name=3D"hibernate.connection.url" value=3D&= quot;jdbc:hsqldb:file:../temp/data/exodb"/> + <property name=3D"hibernate.connection.driver_class" = value=3D"org.hsqldb.jdbcDriver"/> +... + </properties-param> + </init-params> + </component> + + In the org.exoplatform.services.database.impl.Hibernat= eServiceImpl you will find that the name "hibernate.properties" o= f the properties-param is used to access the properties. + + package org.exop= latform.services.database.impl; + +public class HibernateServiceImpl implements HibernateService, ComponentRe= questLifecycle { + public HibernateServiceImpl(InitParams initParams, CacheService cacheSer= vice) { + PropertiesParam param =3D initParams.getPropertiesParam("hibernat= e.properties"); +... +} + + + The value specification for <value-param> elements i= s a <value> element which defines a String instanc= e. + + + + The value specification for <values-param> requires = one or more <value> elements. Each <value> represents one String instance. All String values are the= n collected into a java.util.List instance. + + + + <value-param> Example + <component> + <key>org.exoplatform.portal.config.UserACL</key> + <type>org.exoplatform.portal.config.UserACL</type> = + <init-params> = +... + <value-param> + <name>access.control.workspace</name> + <description>groups with memberships that have the right to = access the User Control Workspace</description> + <value>*:/platform/administrators,*:/organization/management= /executive-board</value> = + </value-param> = +... + </component> + + The UserACL class accesses to the <value-param> = in its constructor. + + package org.exop= latform.portal.config; +public class UserACL { + + public UserACL(InitParams params) { + UserACLMetaData md =3D new UserACLMetaData(); + ValueParam accessControlWorkspaceParam =3D params.getValueParam("= access.control.workspace"); + if(accessControlWorkspaceParam !=3D null) md.setAccessControlWorkspace= (accessControlWorkspaceParam.getValue()); +... + + + For <object-param> entries, the value specification = consists of an <object> element which is used for plain Java style ob= ject specification (specifying an implementation class - <type= >, and property values - <field>). + + + <object-param> and LDAP Example + + Let's have a look at the configuration of the LDA= PService. It is not important to understand LDAP, we only discuss the param= eters as they relate to <object-param>. + + <component> + <key>org.exoplatform.services.LDAP.LDAPService</key> + <type>org.exoplatform.services.LDAP.impl.LDAPServiceImpl</typ= e> + <init-params> + <object-param> + <name>LDAP.config</name> + <description>Default LDAP config</description> + <object type=3D"org.exoplatform.services.LDAP.impl.LDAPCon= nectionConfig"> = + <field name=3D"providerURL"><string>LDAPs://10.0= .0.3:636</string></field> + <field name=3D"rootdn"><string>CN=3DAdministrato= r,CN=3DUsers,DC=3Dexoplatform,DC=3Dorg</string></field> + <field name=3D"password"><string>exo</string&= gt;</field> + <field name=3D"version"><string>3</string>= </field> + <field name=3D"minConnection"><int>5</int&g= t;</field> + <field name=3D"maxConnection"><int>10</in= t></field> = + <field name=3D"referralMode"><string>ignore&= lt;/string></field> + <field name=3D"serverName"><string>active.di= rectory</string></field> + </object> + </object-param> + </init-params> +</component> + + You see here an <object-param> element is being = used to pass the parameters inside an object (actually a java bean). It con= sists of a name, a description and exactly one object. The object defines the type an= d a number of fields. + + + Here you see how the service accesses the object: + + package org.exop= latform.services.LDAP.impl; + +public class LDAPServiceImpl implements LDAPService { +... + public LDAPServiceImpl(InitParams params) { + LDAPConnectionConfig config =3D (LDAPConnectionConfig) params.getObjec= tParam("LDAP.config") + .getObject(= ); +... + + The passed object is LDAPConnectionConfig which is a c= lassic java bean. It contains all fields= and also the appropriate getters and setters (not listed here). You also c= an provide default values. The container creates a new instance of your bea= n and calls all setters whose values are configured in the configuration fi= le. + + package org.exop= latform.services.LDAP.impl; + +public class LDAPConnectionConfig { + private String providerURL =3D "LDAP://127.0.0.1:389"; + private String rootdn; + private String password; = + private String version; = + private String authenticationType =3D "simple"; + private String serverName =3D "default"; + private int minConnection; + private int maxConnection; + private String referralMode =3D "follow"; +... + + You see that the types (String, int) of the fields in = the configuration correspond with the bean. A short glance in the kernel_1_= 2.xsd file let us discover more simple types: + + + + + string, int, long, boo= lean, date, double + + + + + Have a look on this type test xml file: https://anonsvn.jboss.org/repos/exo-jcr/kerne= l/trunk/exo.kernel.container/src/test/resources/object.xml. + + + + The following section has an example of specifying a field= of with a Collection type. + + + The <init-params> structure (the names and types of = entries) is specific for each service, as it is the code inside a service c= omponents' class that defines which entry names to look up and what ty= pes it expects to find. + +
+ Collection + + You also can use java collections to configure your se= rvice. In order to see an example, let's open the database-organizatio= n-configuration.xml file. This file defines a default user organization (us= ers, groups, memberships/roles) of your portal. They use component-plugins = which are explained later. You will see that object-param is used again. + + + There are two collections: The first collection is an = ArrayList. This ArrayList contains only = one value, but there could be more. The only value is an object which defin= es the field of the NewUserConfig$JoinGroup bean. + + + The second collection is a Has= hSet that is a set of strings. + + <component-= plugin> + <name>new.user.event.listener</name> + <set-method>addListenerPlugin</set-method> + <type>org.exoplatform.services.organization.impl.NewUserEventL= istener</type> + <description>this listener assign group and membership to a ne= w created user</description> + <init-params> + <object-param> + <name>configuration</name> + <description>description</description> + <object type=3D"org.exoplatform.services.organization.im= pl.NewUserConfig"> + <field name=3D"group"> + <collection type=3D"java.util.ArrayList"> + <value> + <object type=3D"org.exoplatform.services.organiz= ation.impl.NewUserConfig$JoinGroup"> + <field name=3D"groupId"><string>= ;/platform/users</string></field> + <field name=3D"membership"><string= >member</string></field> + </object> + </value> = + </collection> + </field> + <field name=3D"ignoredUser"> + <collection type=3D"java.util.HashSet"> + <value><string>root</string></value&g= t; + <value><string>john</string></value&g= t; + <value><string>marry</string></value&= gt; + <value><string>demo</string></value&g= t; + <value><string>james</string></value&= gt; + </collection> + </field> + </object> + </object-param> + </init-params> + </component-plugin> + + Let's look at the org.exoplatform.services.organi= zation.impl.NewUserConfig bean: + + public class New= UserConfig { + private List role; + private List group; + private HashSet ignoredUser; + + ... + + public void setIgnoredUser(String user) { + ignoredUser.add(user); + + ... + + static public class JoinGroup { + public String groupId; + public String membership; + ... +} + + You see the values of the HashSet are set one by one b= y the container, and it's the responsibility of the bean to add these = values to its HashSet. + + + The JoinGroup object is just an inner class and implem= ents a bean of its own. It can be accessed like any other inner class using= NewUserConfig.JoinGroup. + +
+
+
+ Component Plug-in Priority + + Since kernel version 2.0.6 it is possible to setup order o= f loading for ComponentPlugin. Use the ' prior= ity' tag to define plug-in's load priority. By default all plug-ins get priority '0'; they will be loaded in the container&a= pos;s natural way. If you want one plug-in to be loaded later than the othe= rs then just set priority for it higher than zero. + + + Simple example of fragment of a co= nfiguration.xml. + + ... +<component> + <type>org.exoplatform.services.Component1</type> +</component> + +<external-component-plugins> + <target-component>org.exoplatform.services.Component1</target-c= omponent> + + <component-plugin> + <name>Plugin1</name> + <set-method>addPlugin</set-method> + <type>org.exoplatform.services.plugins.Plugin1</type> + <description>description</description> + <priority>1</priority> + </component-plugin> + + <component-plugin> + <name>Plugin2</name> + <set-method>addPlugin</set-method> + <type>org.exoplatform.services.plugins.Plugin2</type> + <description>description</description> + <priority>2</priority> + </component-plugin> + +</external-component-plugins> + +<external-component-plugins> + <target-component>org.exoplatform.services.Component1</target-c= omponent> + <component-plugin> + <name>Plugin3</name> + <set-method>addPlugin</set-method> + <type>org.exoplatform.services.plugins.Plugin3</type> + <description>description</description> + </component-plugin> +</external-component-plugins> +... + + In the above example plug-in 'Plugin3' will be l= oaded first because it has the default priority '0'. Then, plug-i= n 'Plugin1' will be loaded and last one is plug-in 'Plugin2&= apos;. + +
+
+ Configuration Logging + + In case you need to solve problems with your service confi= guration, you have to know from which JAR/WAR causes your troubles. Add the= JVM system property org.exoplatform.container.configuration.deb= ug to your eXo.bat or eXo.sh file (exo-tomcat/bin/). + + set EXO_CONFIG_OPTS=3D"-Dorg.exoplatform.cont= ainer.configuration.debug" + + If this property is set the container configuration manage= r reports during startup the configuration retrieval process to the standar= d output (System.out). + + ...... +Add configuration jar:file:/D:/Projects/eXo/dev/exo-working/exo-tomcat/lib= /exo.kernel.container-trunk.jar!/conf/portal/configuration.xml +Add configuration jar:file:/D:/Projects/eXo/dev/exo-working/exo-tomcat/lib= /exo.kernel.component.cache-trunk.jar!/conf/portal/configuration.xml +Add configuration jndi:/localhost/portal/WEB-INF/conf/configuration.xml im= port jndi:/localhost/portal/WEB-INF/conf/common/common-configuration.xml +import jndi:/localhost/portal/WEB-INF/conf/database/database-configuration= .xml import jndi:/localhost/portal/WEB-INF/conf/ecm/jcr-component-plugins-c= onfiguration.xml +import jndi:/localhost/portal/WEB-INF/conf/jcr/jcr-configuration.xml +...... +
+
+ Import + + The import tag allows to link to other configuration files= . These imported files can be placed anywhere. If you write a default confi= guration which is part of your jar file you should not import files from ou= tside your jar. + + + + + war: Imports fr= om portal.war/WEB-INF + + + + + jar or classpath: Uses the clas= sloader, you can use this prefix in the default configuration fo= r importing an other configuration file which is accessible by the classloa= der. + + + + + file: Uses an <= emphasis role=3D"bold">absolute path, you also can put a URL. + + + + + without any prefix: + + + + + If you open the portal/trunk/web/portal/src/main= /webapp/WEB-INF/conf/configuration.xml you will see that it cons= ists only of imports: + + <import>war:/c= onf/common/common-configuration.xml</import> +<import>war:/conf/common/logs-configuration.xml</import> +<import>war:/conf/database/database-configuration.xml</import> +<import>war:/conf/jcr/jcr-configuration.xml</import> +<import>war:/conf/common/portlet-container-configuration.xml</imp= ort> +... +
+
+ System properties + + Since kernel 2.0.7 and 2.1, it is possible to use system p= roperties in literal values of component configuration meta data. This make= s it possible to resolve properties at runtime instead of providing a value= at packaging time. + + + In portal/trunk/web/portal/src/main/webapp/WEB-INF/conf/da= tabase/database-configuration.tmpl.xml you find an example for system prope= rties: + + <component> + <key>org.exoplatform.services.database.HibernateService</key&= gt; + <jmx-name>database:type=3DHibernateService</jmx-name> + <type>org.exoplatform.services.database.impl.HibernateServiceImp= l</type> + <init-params> + <properties-param> + <name>hibernate.properties</name> + <description>Default Hibernate Service</description> +... + <property name=3D"hibernate.connection.url" value=3D&= quot;${connectionUrl}"/> + <property name=3D"hibernate.connection.driver_class" = value=3D"${driverClass}"/> + <property name=3D"hibernate.connection.username" valu= e=3D"${username}"/> + <property name=3D"hibernate.connection.password" valu= e=3D"${password}"/> + <property name=3D"hibernate.dialect" value=3D"${= dialect}"/> +... + </properties-param> + </init-params> + </component> + + As these are system properties you use the -D command: java -DconnectionUrl=3Djdbc:hsqldb:file:../temp/data/e= xodb -DdriverClass=3Dorg.hsqldb.jdbcDriver Or better use the par= ameters of eXo.bat / eXo.sh when you start JBoss Portal Platform: set EXO_OPTS=3D"-DconnectionUrl=3Djdbc:hsqldb:file:../t= emp/data/exodb -DdriverClass=3Dorg.hsqldb.jdbcDriver" + +
+
+
+
+ Specific Services +
+ ListenerService +
+ Asynchronous Event Broadcast + + Basically, ListenerService used to store Listeners and broadcast event= s to them. + + + ListenerService event broadcasting works in next way - it takes a dest= ination listeners and executes event on those listeners. + + + But, some events may take a lot of time, so idea to make event process= ing asynchronous is useful. + +
+ + What do I need to make my listener asynchronous? + +
+ + - It's very simple, just mark your Listener implementation as @Asynchronous. + + @Asynchronous +class AsynchListenerWithException<S,D> extends Listener<S,D> +{ + @Override + public void onEvent(Event<S,D> event) throws Exception + { + // some expensive operation + } +} + + Now, our AsynchListener will be executed in separate thread by ExecutorService. + + + By default, ExecutoreService configured with th= read pool size 1, you can change it in configuration: + + <component> + <key>org.exoplatform.services.listener.ListenerService</key= > + <type>org.exoplatform.services.listener.ListenerService</ty= pe> + = + <init-params> + <value-param> + <name>asynchPoolSize</name> + <value>5</value> + </value-param> + </init-params> + + </component> +
+
+
+ Understanding the ListenerService +
+ Objectives + + This article will first describe how the ListenerService works and the= n it will show you how to configure the ListenerService. + +
+
+ What is the ListenerService ? + + Inside eXo, an event mechanism allows to trigger and listen to events = under specific conditions. This mechanism is used in several places in eXo = such as login/logout time. + +
+
+ How does it work? + + Listeners must be subclasses of org.exoplatform.services.listener.List= ener registered by the ListenerService. + +
+ Registering a listener + + To register a listener, you need to call the addListener() method. + + /** + * This method is used to register a listener with the service. The method + * should: 1. Check to see if there is a list of listener with the listener + * name, create one if the listener list doesn't exit 2. Add the new = listener + * to the listener list + * = + * @param listener +*/ +public void addListener(Listener listener) { + ... +} + + By convention, we use the listener name as the name of the event to l= isten to. + +
+
+ Triggering an event + + To trigger an event, an application can call one of the broadcast() m= ethods of ListenerService. + + /** + * This method is used to broadcast an event. This method should: 1. Check= if + * there is a list of listener that listen to the event name. 2. If there = is a + * list of listener, create the event object with the given name , source = and + * data 3. For each listener in the listener list, invoke the method + * onEvent(Event) + * = + * @param <S> The type of the source that broadcast the event + * @param <D> The type of the data that the source object is working= on + * @param name The name of the event + * @param source The source object instance + * @param data The data object instance + * @throws Exception = + */ +public <S, D> void broadcast(String name, S source, D data) throws E= xception { + ... +} + +/** + * This method is used when a developer want to implement his own event ob= ject + * and broadcast the event. The method should: 1. Check if there is a list= of + * listener that listen to the event name. 2. If there is a list of the + * listener, For each listener in the listener list, invoke the method + * onEvent(Event) + * = + * @param <T> The type of the event object, the type of the event ob= ject has + * to be extended from the Event type + * @param event The event instance + * @throws Exception + */ +public <T extends Event> void broadcast(T event) throws Exception { + ... +} + + The broadcast() methods retrieve the name of the event and find the r= egistered listeners with the same name and call the method onEvent() on eac= h listener found. + + + Each listener is a class that extends org.exoplatform.services.listen= er.Listener, as you can see below: + + public abstract = class Listener<S, D> extends BaseComponentPlugin { + + /** + * This method should be invoked when an event with the same name is + * broadcasted + */ + public abstract void onEvent(Event<S, D> event) throws Exception; +} + + + As you can see we use generics to limit the source of the event to t= he type 'S' and the data of the event to the type 'D', = so we expect that listeners implement the method onEvent() with the corresp= onding types + + + + Each listener is also a ComponentPlugin with a name and a description= , in other words, the name of the listener will be the name given in the co= nfiguration file, for more details see the next section. + + public interface= ComponentPlugin { + public String getName(); + + public void setName(String name); + + public String getDescription(); + + public void setDescription(String description); +} +
+
+
+ How to configure a listener? + + All listeners are in fact a ComponentPlugin so it must be configured a= s below: + + <?xml version=3D&= quot;1.0" encoding=3D"ISO-8859-1"?> +<configuration> +... + <external-component-plugins> + <!-- The full qualified name of the ListenerService --> = + <target-component>org.exoplatform.services.listener.ListenerServ= ice</target-component> + + <component-plugin> + <!-- The name of the listener that is also the name of the target e= vent --> + <name>${name-of-the-target-event}</name> + <!-- The name of the method to call on the ListenerService in ord= er to register the Listener --> + <set-method>addListener</set-method> + <!-- The full qualified name of the Listener --> + <type>${the-FQN-of-the-listener}</type> + </component-plugin> + + </external-component-plugins> +</configuration> +
+
+ Concrete Example + + The org.exoplatform.services.security.ConversationRegistry uses the Li= stenerService to notify that a user has just signed in or just left the app= lication. For example, when a new user signs in, the following code is call= ed: + + listenerService.br= oadcast("exo.core.security.ConversationRegistry.register", this, = state); + + This code will in fact create a new Event which name is "exo.core= .security.ConversationRegistry.register", which source is the current = instance of ConversationRegistry and which data is the given state. The Lis= tenerService will call the method onEvent(Event<ConversationRegistry, Co= nversationState> event) on all the listeners which name is "exo.cor= e.security.ConversationRegistry.register". + + + In the example below, we define a Listener that will listen the event = "exo.core.security.ConversationRegistry.register". + + <?xml version=3D&= quot;1.0" encoding=3D"ISO-8859-1"?> +<configuration> +... + <external-component-plugins> + <!-- The full qualified name of the ListenerService --> = + <target-component>org.exoplatform.services.listener.ListenerServ= ice</target-component> + + <component-plugin> + <!-- The name of the listener that is also the name of the target= event --> + <name>exo.core.security.ConversationRegistry.register</name= > + <!-- The name of the method to call on the ListenerService in ord= er to register the Listener --> + <set-method>addListener</set-method> + <!-- The full qualified name of the Listener --> + <type>org.exoplatform.forum.service.AuthenticationLoginListene= r</type> + </component-plugin> + + </external-component-plugins> +</configuration> +... +
+
+
+ Job Schedule +
+ What is Job Scheduler? + + Job scheduler defines a job to exec= ute a given number of times during a given period. It is a service that is = in charge of unattended background executions, commonly known for historica= l reasons as batch processing. It is used to create and run jobs automatica= lly and continuously, to schedule event-driven jobs and reports. + +
+
+ How does Job Scheduler work? + + Jobs are scheduled to run when a given Trigger occurs. Triggers can be= created with nearly any combination of the following directives: + + + + + at a certain time of day (to the millisecond) + + + + + on certain days of the week + + + + + + + on certain days of the month + + + + + on certain days of the year + + + + + + + not on certain days listed within a registered Calendar (such as bus= iness holidays) + + + + + + + repeated a specific number of times + + + + + + + repeated until a specific time/date + + + + + repeated indefinitely + + + + + + + repeated with a delay interval + + + + + Jobs are given names by their creator and can also be organized into n= amed groups. Triggers may also be given names and placed into groups, in or= der to easily organize them within the scheduler. Jobs can be added to the = scheduler once, but registered with multiple Triggers. Within a J2EE enviro= nment, Jobs can perform their work as part of a distributed (XA) transactio= n. + + + (Source: quartz-scheduler.org) + +
+ How can Job Scheduler Service be used in Kernel? + + Kernel leverages Quart= z for its scheduler service and wraps org.quartz.Schedul= er in org.exoplatform.services.scheduler.impl.Quartz= Sheduler for easier service wiring and configuration like any o= ther services. To work with Quartz in Kernel, you will mostly work with org.exoplatform.services.scheduler.JobSchedulerService = (implemented by org.exoplatform.services.scheduler.impl.JobSched= ulerServiceImpl. + + + To use JobSchedulerService, you can configure = it as a component in the configuration.xml. Because JobScheduler= Service requires QuartzSheduler and QueueTasks, you also have to configure these two compone= nts. + + <?xml version= =3D"1.0" encoding=3D"UTF-8"?> +<configuration + xmlns:xsi=3D"http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation=3D"http://www.exoplaform.org/xml/ns/kernel_1_2.x= sd http://www.exoplaform.org/xml/ns/kernel_1_2.xsd" + xmlns=3D"http://www.exoplaform.org/xml/ns/kernel_1_2.xsd"> + + <component> + <type>org.exoplatform.services.scheduler.impl.QuartzSheduler<= /type> + </component> + + <component> + <type>org.exoplatform.services.scheduler.QueueTasks</type> + </component> + + <component> + <key>org.exoplatform.services.scheduler.JobSchedulerService</= key> + <type>org.exoplatform.services.scheduler.impl.JobSchedulerServic= eImpl</type> + </component> + +</configuration> +
+
+ Samples + + + You can download the project code from here + + + + Work with JobSchedulerService by creating a sa= mple project and use JBoss Portal Platform for testing. + + + Firstly, create a project by using maven archetype plug-in: + + mvn archetype:generate + + + + + For project type: select maven-archetype-qu= ickstart + + + + + For groupId: select org.exoplatform.samples= + + + + + For artifactId: select exo.samples.schedule= r + + + + + For version: select 1.0.0-SNAPSHOT + + + + + For package: select org.exoplatform.samples= .scheduler + + + + + Edit the pom.xml as follows: + + <project + xmlns=3D"http://maven.apache.org/POM/4.0.0" + xmlns:xsi=3D"http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation=3D"http://maven.apache.org/POM/4.0.0 http://mave= n.apache.org/maven-v4_0_0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <artifactId>exo.portal.parent</artifactId> + <groupId>org.exoplatform.portal</groupId> + <version>3.1.0-GA</version> + </parent> + + <groupId>org.exoplatform.samples</groupId> + <artifactId>exo.samples.scheduler</artifactId> + <version>1.0.0-SNAPSHOT</version> + <name>eXo Samples For Scheduler</name> + <description>eXo Samples Code For Scheduler</description> +</project> + + Generate an eclipse project by using maven eclipse plug-in and then i= mport into eclipse: + + mvn eclipse:eclipse + + eXo Kernel makes it easier to work with job scheduler service. All yo= u need is just to define your "job" class to be performed by impl= ementing org.quartz.Job interface and = add configuration for it. + +
+ Define a job + + To define a job, do as follows: + + + Define your job to be performed. For example, the job DumbJob is defined as follows: + + package org.ex= oplatform.samples.scheduler.jobs; + +import org.exoplatform.services.log.ExoLogger; +import org.exoplatform.services.log.Log; +import org.quartz.Job; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; + +/** + * DumbJob for executing a defined dumb job. + */ +public class DumbJob implements Job { + + /** + * The logger + */ + private static final Log LOG =3D ExoLogger.getLogger(DumbJob.class); + + /** + * The job of the DumbJob will be done by executing this method. + * + * @param context + * @throws JobExecutionException + */ + public void execute(JobExecutionContext context) throws JobExecutionExce= ption { + LOG.info("DumbJob is executing..."); + } +} + + All jobs are required to implement the method execute from org.quartz.Job interface. This method will be called whenever a job is performed. Wit= h DumbJob, you just use logging to see= that it will work. By looking at the terminal, you will see the log messag= e: "DumbJob is executing..." + +
+
+ Job configuration + + After defining the "job", the only next step is to configu= re it by using external-component-plugin configuration for org.exoplatform.services.sch= eduler.JobSchedulerService. You can use these methods below for = setting component plug-in: + + public void ad= dPeriodJob(ComponentPlugin plugin) throws Exception; + + The component plug-in for this method must be the type of org.exoplatform.services.scheduler.PeriodJob. Th= is type of job is used to perform actions that are executed in a period of = time. You have to define when this job is performed, when it ends, when it = performs the first action, how many times it is executed and the period of = time to perform the action. See the configuration sample below to understan= d more clearly: + + <external-com= ponent-plugins> + <target-component>org.exoplatform.services.scheduler.JobScheduler= Service</target-component> + <component-plugin> + <name>PeriodJob Plugin</name> + <set-method>addPeriodJob</set-method> + <type>org.exoplatform.services.scheduler.PeriodJob</type> + <description>period job configuration</description> + <init-params> + <properties-param> + <name>job.info</name> + <description>dumb job executed periodically</descripti= on> + <property name=3D"jobName" value=3D"DumbJob&qu= ot;/> + <property name=3D"groupName" value=3D"DumbJobG= roup"/> + <property name=3D"job" value=3D"org.exoplatfor= m.samples.scheduler.jobs.DumbJob"/> + <property name=3D"repeatCount" value=3D"0"= ;/> + <property name=3D"period" value=3D"60000"= /> + <property name=3D"startTime" value=3D"+45"= ;/> + <property name=3D"endTime" value=3D""/> + </properties-param> + </init-params> + </component-plugin> + </external-component-plugins> + public void ad= dCronJob(ComponentPlugin plugin) throws Exception; + + The component plug-in for this method must be the type of org.exoplatform.services.scheduler.CronJob. This= type of job is used to perform actions at specified time with Unix 'c= ron-like' definitions. The plug-in uses "expression" field f= or specifying the 'cron-like' definitions to execute the job. Thi= s is considered as the most powerful and flexible job to define when it wil= l execute. For example, at 12pm every day =3D> "0 0 12 * * ?";= or at 10:15am every Monday, Tuesday, Wednesday, Thursday and Friday =3D>= ; "0 15 10 ? * MON-FRI". To see more about Cron expression, pleas= e refer to this article: CRON expression. See the configuration sample below to un= derstand more clearly: + + <external-com= ponent-plugins> + <target-component>org.exoplatform.services.scheduler.JobSchedule= rService</target-component> + <component-plugin> + <name>CronJob Plugin</name> + <set-method>addCronJob</set-method> + <type>org.exoplatform.services.scheduler.CronJob</type> + <description>cron job configuration</description> + <init-params> + <properties-param> + <name>job.info</name> + <description>dumb job executed by cron expression</desc= ription> + <property name=3D"jobName" value=3D"DumbJob&qu= ot;/> + <property name=3D"groupName" value=3D"DumbJobG= roup"/> + <property name=3D"job" value=3D"org.exoplatfor= m.samples.scheduler.jobs.DumbJob"/> + <!-- The job will be performed at 10:15am every day --> + <property name=3D"expression" value=3D"0 15 10= * * ?"/> = + </properties-param> + </init-params> + </component-plugin> + </external-component-plugins> + public void ad= dGlobalJobListener(ComponentPlugin plugin) throws Exception; + public void ad= dJobListener(ComponentPlugin plugin) throws Exception; + + The component plug-in for two methods above must be the type of org.quartz.JobListener. This job listener = is used so that it will be informed when a org.qu= artz.JobDetail executes. + + public void ad= dGlobalTriggerListener(ComponentPlugin plugin) throws Exception; + public void ad= dTriggerListener(ComponentPlugin plugin) throws Exception; + + The component plug-in for two methods above must be the type of org.quartz.TriggerListener. This trigger l= istener is used so that it will be informed when a org.quartz.Trigger fires. + +
+
+ Run the project + + Create conf.portal package in y= our sample project. Add the configuration.xml file with the content as foll= ows: + + <?xml version= =3D"1.0" encoding=3D"UTF-8"?> +<configuration + xmlns:xsi=3D"http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation=3D"http://www.exoplaform.org/xml/ns/kernel_1_2.x= sd http://www.exoplaform.org/xml/ns/kernel_1_2.xsd" + xmlns=3D"http://www.exoplaform.org/xml/ns/kernel_1_2.xsd"> + + <component> + <type>org.exoplatform.services.scheduler.impl.QuartzSheduler<= /type> + </component> + <component> + <type>org.exoplatform.services.scheduler.QueueTasks</type> + </component> + <component> + <key>org.exoplatform.services.scheduler.JobSchedulerService</= key> + <type>org.exoplatform.services.scheduler.impl.JobSchedulerServic= eImpl</type> + </component> + + <external-component-plugins> + <target-component>org.exoplatform.services.scheduler.JobSchedule= rService</target-component> + <component-plugin> + <name>PeriodJob Plugin</name> + <set-method>addPeriodJob</set-method> + <type>org.exoplatform.services.scheduler.PeriodJob</type> + <description>period job configuration</description> + <init-params> + <properties-param> + <name>job.info</name> + <description>dumb job executed periodically</descriptio= n> + <property name=3D"jobName" value=3D"DumbJob&qu= ot;/> + <property name=3D"groupName" value=3D"DumbJobG= roup"/> + <property name=3D"job" value=3D"org.exoplatfor= m.samples.scheduler.jobs.DumbJob"/> + <property name=3D"repeatCount" value=3D"0"= ;/> + <property name=3D"period" value=3D"60000"= /> + <property name=3D"startTime" value=3D"+45"= ;/> + <property name=3D"endTime" value=3D""/> + </properties-param> + </init-params> + </component-plugin> + </external-component-plugins> +</configuration> + + mvn clean install the project. = Copy .jar file to lib in tomcat bundle= d with JBoss Portal Platform 6. Run bin/gatein.sh= to see the DumbJob to be e= xecuted on the terminal when portal containers are initialized. Please look= at the terminal to see the log message of DumbJo= b. + + + From now on, you can easily create any job to be executed in JBoss P= ortal Platform's portal by defining your job and configuring it. + +
+
+
+
+ Reference + + To further understand about Job Scheduler, you can refer the following= links: + + + + + http://www.quartz-sc= heduler.org/ + + + + + http://en.= wikipedia.org/wiki/Job_scheduler + + + + + http://www.theserverside.com/news/1364726/Job-Sche= duling-in-J2EE-Applications + + + + + http://technet.microsoft.com/en-us/library/cc720070%28WS.10%= 29.aspx + + + +
+
+
+ The data source provider +
+ Description + + The DataSourceProvider is a service used to give = access to a data source in an uniform manner in order to be able to support= data sources that are managed by the application server. + + + + List methods + + + + getDataSource(String dataSourceName) + Tries to get the data source from a JNDI lookup.= If it can be found and the data source is defined as managed, the service = will wrap the original DataSource instance in a new DataSource instance that is aware of its manag= ed state otherwise it will return the original DataSou= rce instance. + + + isManaged(String dataSourceName) + Indicates whether or not the given data source i= s managed. + + + +
+ +
+
+
+ Configuration + + The configuration of the DataSourceProvider shoul= d be defined only if you use managed data sources since by default all the = data sources are considered as not managed. See below the default configura= tion + + <configuration> +.... = + <component> + <key>org.exoplatform.services.jdbc.DataSourceProvider</key&= gt; + <type>org.exoplatform.services.jdbc.impl.DataSourceProviderImp= l</type> + <init-params> + <!-- Indicates that the data source needs to check if a tx is= active + to decide if the provided connection needs to be managed or = not. + If it is set to false, the data source will provide only + managed connections if the data source itself is managed. -= -> + <!--value-param> + <name>check-tx-active</name> + <value>true</value> + </value-param--> + <!-- Indicates that all the data sources are managed = + If set to true the parameter never-managed and = + managed-data-sources will be ignored --> + <!--value-param> + <name>always-managed</name> + <value>true</value> + </value-param--> + <!-- Indicates the list of all the data sources that are = + managed, each value tag can contain a list of + data source names separated by a comma, in the + example below we will register ds-foo1, ds-foo2 = + and ds-foo3 as managed data source. If always-managed + and/or never-managed is set true this parameter is ignored -= -> + <!--values-param> + <name>managed-data-sources</name> + <value>ds-foo1, ds-foo2</value> + <value>ds-foo3</value> + </values-param--> + </init-params> + </component> = +... +</configuration> + + Fields description + + + + + check-tx-active + + This parameter indicates that the data source need= s to check if a transaction is active to decide if the provided connection = needs to be managed or not. If it is set to false, the= data source will provide only managed connections if the data source itsel= f is managed. By default, this parameter is set to true. If this parameter is set to true, it will need the = TransactionService to work properly, so please ensure = that the TransactionService is defined in your configu= ration. + + + + always-managed + + This parameter indicates that all the data sources= are managed. If set to true the parameter n= ever-managed and managed-data-sources will = be ignored, so it will consider all the data sources as managed. By default= , this parameter is set to false. + + + + managed-data-sources + + This parameter indicates the list of all the data = sources that are managed, each value tag can contain a list of data source = names separated by a comma. If always-managed and/or <= emphasis>never-managed is set true this par= ameter is ignored. + + + +
+
+
+
+
+ Configuring a portal container + + A portal container is defined by several attributes: + + + + Portal Container Name + + + This attribute is always equal to the URL context to which the curren= t portal is bound. + + + + + REST Context Name + + + This attribute is used for REST access to portal application; every p= ortal has one unique REST context name. + + + + + Realm Name + + + This is the name of the security realm used for authentication when u= sers log into the portal. + + + + + Dependencies + + + This is a list of other web applications whose resources are visible = to the current portal (via the extension mechanism described later), and ar= e searched for in the specified order. + + + + + + + Dependencies are part of the extension mechanism= which is discussed later in this document. + + + Every PortalContainer is represented by a Po= rtalContainer instance, which contains: + + + + eXoContainerContext + + + This contains information about the portal. + + + + + Unified Servlet Context + + + This deals with web-archive-relative resource loading. + + + + + Unified Classloader + + + For classpath based resource loading. + + + + + Various methods for retrieving services + + + + + + + + + The Unified servlet context and unified classloader are part of the extension mechanism (which is detailed in the nex= t section). + + + They provide the standard API (ServletContext, ClassLoader) with specific resource loading behavior, such as = visibility into associated web application archives, configured with the de= pendencies property of PortalContainerDefinition. + + + Resources from other web applications are queried in the order specified= by the dependencies. The later entries in the list override the previous o= nes. + +
+
+ System property configuration + + A new property configuration service has been developed for taking care = of configuring system properties from the inline kernel configuration or fr= om specified property files. + + + The service is scoped at the root container level because it is used by = all the services in the different portal containers in the application runt= ime. + +
+ Properties <init-param> + + The properties init param takes a property declared to configure variou= s properties. + + <component> + <key>PropertyManagerConfigurator</key> + <type>org.exoplatform.container.PropertyConfigurator</type> + <init-params> + <properties-param> + <name>properties</name> + <property name=3D"foo" value=3D"bar"/> + </properties-param> + </init-params> +</component> +
+
+ Properties URL <init-param> + + The properties URL init param allow to load an external file by specify= ing its URL. Both property and XML format are supported, see the javadoc of= the + java.util.Properties + class for more information. When a property file is lo= aded the various property declarations are loaded in the order in which the= properties are declared sequentially in the file. + + <component> + <key>PropertyManagerConfigurator</key> + <type>org.exoplatform.container.PropertyConfigurator</type> + <init-params> + <value-param> + <name>properties.url</name> + <value>classpath:configuration.properties</value> + </value-param> + </init-params> +</component> + + In the properties file corresponding to the external properties, you ca= n reuse variables before defining to create a new variable. In this case, t= he prefix "portal.container." is not needed,= see an example below: = +my-var1=3Dvalue 1 +my-var2=3Dvalue 2 +complex-value=3D${my-var1}-${my-var2} + + +
+
+ System Property configuration of the properties URL + + It is possible to replace the properties URL init param by a system pro= perty that overwrites it. The name of that property is exo.proper= ties.url. + +
+
+ Variable Syntaxes + + All the variables that we described in the previous sections can be def= ined thanks to 2 possible syntaxes which are ${variable-name} or ${variable-name:default-value}. The first s= yntax doesn't define any default value so if the variable has not be s= et the value will be ${variable-name} to indicate that= it could not be resolved. The second syntax allows you to define the defau= lt value after the semi colon so if the variable has not be set the value w= ill be the given default value. + +
+
+
+ The Extension Mechanism and Portal Extensions + + The Extension mechanism makes it poss= ible to override portal resources in a way similar to hardware plug-and-pla= y functionalities. + + + Customizations can be implemented without unpacking and repacking the or= iginal portal .war archives by adding a .war arch= ive to the resources and configuring its position in the portal's clas= spath. Custom .war archives can be created with new resources = that override the resources in the original archive. + + + These archives, packaged for use through the extension mechanism, are ca= lled portal extensions. + + + Creating a portal extension + + + Declare the PortalConfigOwner servl= et context listener in the web.xml of your web applica= tion. + + + This example shows a portal extension called s= ample-ext. + + + + + + Add the application's servlet context name to the Portal= ContainerDefinition's list of dependencies. This must be don= e for each portal container that you want to have access to the new applica= tion. + + + The application's position in these lists will dictate its priori= ty when the portal loads resources. The later your application appears in t= he list, the higher its resource priority will be. + + + + + At this point your new web archive will be on both the portal's u= nified classpath and unified servlet context resource path. + + + + + Example + + Refer to the code extract in for an example of a PortalContainerD= efinition that has sample-ext = in its list of dependencies. + + +
+ Running Multiple Portals + + It is possible to run several independent portal containers, each bound= to a different URL context, within the same JVM instance. + + + This method of deployment allows for efficient administration and resou= rce consumption by allowing coexisting portals to reuse configuration arrangements through the extension mechanism. + + + Portals can inherit resources and configuration fr= om existing web archives and add extra resources as needed, overr= iding those that need to be changed by including modified copies. + + + In order for a portal application to function correctly when deployed w= ithin a multiple portal deployment, it may have to dynamically query the in= formation about the current portal container. The application should not ma= ke any assumptions about the name, and other information of the current por= tal, as there are now multiple different portals in play. + + + At any point during request processing, or life-cycle event processing,= an application can retrieve this information through org.exoplatf= orm.container.eXoContainerContext. + + + Sometimes an application must ensure that the proper PortalCon= tainer is associated with the current eXoContainerContex= t call. + + + If the portal application contains servlets or servlet filters that nee= d to access portal specific resources during their request processing, the = servlet or filter must be associated with the current container. + + + A servlet in this instance should extend the org.exoplatform.c= ontainer.web.AbstractHttpServlet class so as to properly initiali= ze the current PortalContainer. + + + This will also set the current thread's context Classloader to one= that looks for resources in associated web applications in the order speci= fied by the dependencies configuration (= as seen in ). + + + Filter classes need to extend the org.exoplatform.container.we= b.AbstractFilter. + + + Both AbstractHttpServlet, and AbstractFilte= r have a getContainer() method, which returns = the current PortalContainer. + + + If your servlet handles the requests by implementing a service= () method, that method must be renamed to match the following sig= nature: + + + + + This ensures that AbstractHttpServlet's service() interception is not overwritten. + + + + An application may also need access to portal information within the HttpSessionListener. Ensure the abstract c= lass org.exoplatform.container.web.AbstractHttpSess= ionListener is extended. + + + In this instance, modify the method signatures as follows: + + + + Another method must also be implemented in this case: + + + + If this method returns true the current thread&apo= s;s context Classloader is set up according to the = dependencies configuration and availability of the associated we= b applications. + + + If it returns false the standard application separ= ation rules are used for resource loading (effectively turning off the exte= nsion mechanism). + + + This method exists on both AbstractHttpServlet and <= literal>AbstractFilter. This is a default implementation that aut= omatically returns true when it detects there is a cur= rent PortalContainer present and false otherwise. + + + ServletContextListener-based initialization access to Porta= lContainer + +JBoss Portal Platform has no direct control over the deployment of applica= tion archives (.war and .ear files); it is the ap= plication server that performs the deployment. + + + + However, applications in the dependencies configuration must be deployed before the portal= that depends on them is initialized in order for the extension mechanism to work properly. + + + Conversely, some applications may require an already initialized PortalContainer to properly initialize themselves. This gives = rise to a recursive dependency problem. + + + A mechanism of initialization tasks = and task queues has been implemented in = JBoss Portal Platform to resolve this dependency issue. + + + Web applications that depend on a current PortalContainer to initialize must avoid performing their initialization directly on = a ServletContextListener executed during their deploymen= t (before any PortalContainer was initialized). + + + To ensure this, a web application should package its initialization log= ic into an init task of an appropriate type and only use ServletContextListener to insert the init task i= nstance into the proper init tasks queue. + + + An example of this is the Gadgets application which registers Google ga= dgets with the current PortalContainer. This example use= s PortalContainerPostInitTask which is e= xecuted after the portal container has been initialized. + + + + In some situations initialization may be required after the portal container is instantiated but before = it has initialized. PortalContainerPreInitTask can be us= ed in that case. + + + Use PortalContainerPostCreateTask if= initialization is required after all the post-i= nit tasks have been executed. + + + LoginModules + + If some custom LoginModules require the current eXoContainer for initialization ensure they extend org.exoplatform.services.security.jaas.AbstractLoginModule<= /emphasis>. + + + + AbstractLoginModule enforces some basic configuratio= n. It recognizes two initialization options; portal= ContainerName and realmName. + + + The values for these options can be accessed via protected fields of th= e same name. + +
+
+
+ Manageability +
+ Introduction + + The kernel has a framework for exposing a management view of the variou= s sub systems of the platform. The management view is a lose term for defin= ing how we can access relevant information about the system and how we can = apply management operations. JMX is the de facto standard for exposing a ma= nagement view in the Java Platform but we take in consideration other kind = of views such as REST web services. Therefore, the framework is not tied to= JMX, yet it provides a JMX part to define more precisely details related t= o the JMX management view. The legacy framework is still in use but is depr= ecated in favor of the new framework as it is less tested and less efficien= t. It will be removed by sanitization in the future. + +
+
+ Managed framework API + + The managed frameworks define an API for exposing a management view of = objects. The API is targeted for internal use and is not a public API. The = framework leverages Java 5 annotations to describe the management view from= an object. + +
+ Annotations +
+ @org.exoplatform.management.annotations.Managed annotatio= n + + The @Managed annotates elements that wants to expose a management vie= w to a management layer. + + + @Managed for objects + + + The framework will export a management view for the objects annotated. + + + @Managed for getter/setter + + + Defines a managed property. An annotated getter defines a read proper= ty, an annotated setter defines a write property and if matching getter/set= ter are annotated it defines a read/write property. + + + @Managed on method + + + Defines a managed operation. + +
+
+ @org.exoplatform.management.annotations.ManagedDescriptio= n + + The @ManagedDescription annotation provides a description of a manage= d element. It is valid to annotated object or methods. It takes as sole arg= ument a string that is the description value. + +
+
+ @org.exoplatform.management.annotations.ManagedName</titl= e> + <para> + The @ManagedName annotation provides an alternative name for managed = properties. It is used to accomodate legacy methods of an object that can b= e renamed for compatibility reasons. It takes as sole argument a string tha= t is the name value. + </para> + </section> + <section id=3D"sect-Reference_Guide-Annotations-org.exoplatform.ma= nagement.annotations.ManagedBy"> + <title>@org.exoplatform.management.annotations.ManagedBy + + The @ManagedBy annotation defines a delegate class for exposing a man= agement view. The sole argument of the annotation are class literals. The d= elegate class must provide a constructor with the managed object as argumen= t. + +
+
+
+
+ JMX Management View +
+ JMX Annotations +
+ @org.exoplatform.management.jmx.annotations.Property anno= tation + + The @Property annotation is used to within other annotations such as = @NameTemplate or @NamingContext. It should be seen as a structural way for = a list of properties. A property is made of a key and a value. The value ca= n either be a string literal or it can be surrounded by curly brace to be a= dynamic property. A dynamic property is resolved against the instance of t= he object at runtime. + +
+
+ @org.exoplatform.management.jmx.annotations.NameTemplate = annotation + + The @NameTemplate defines a template that is used at registration tim= e of a managed object to create the JMX object name. The template is formed= of properties. + + @NameTemplate({ + @Property(key=3D"container", value=3D"workspace"), + @Property(key=3D"name", value=3D"{Name}")}) +
+
+ @org.exoplatform.management.jmx.annotations.NamingContext= annotation + + The @NamingContext annotation defines a set of properties which are u= sed within a management context. It allows to propagate properties down to = managed objects which are defined by an object implementing the ManagementA= ware interface. The goal is to scope different instances of the same class = that would have the same object name otherwise. + + @NamingContext(@= Property(key=3D"workspace", value=3D"{Name}")) +
+
+
+
+ Example +
+ CacheService example + + The cache service delegates most of the work to the CacheServiceManage= d class by using the @ManagedBy annotation. At runtime when a new cache is = created, it calls the CacheServiceManaged class in order to let the CacheSe= rviceManaged object register the cache. + + @ManagedBy(CacheSe= rviceManaged.class) +public class CacheServiceImpl implements CacheService { + + CacheServiceManaged managed; + ... + synchronized private ExoCache createCacheInstance(String region) throws = Exception { + ... + if (managed !=3D null) { + managed.registerCache(simple); + } + ... + } +} + + The ExoCache interface is annotated to define its management view. The= @NameTemplate is used to produce object name values when ExoCache instance= are registered. + + @Managed +(a)NameTemplate({@Property(key=3D"service", value=3D"cache&= quot;), @Property(key=3D"name", value=3D"{Name}")}) +(a)ManagedDescription("Exo Cache") +public interface ExoCache { + + @Managed + @ManagedName("Name") + @ManagedDescription("The cache name") + public String getName(); + + @Managed + @ManagedName("Capacity") + @ManagedDescription("The maximum capacity") + public int getMaxSize(); + + @Managed + @ManagedDescription("Evict all entries of the cache") + public void clearCache() throws Exception; + + ... +} + + The CacheServiceManaged is the glue code between the CacheService and = the management view. The main reason is that only exo services are register= ed automatically against the management view. Any other managed bean must b= e registered manually for now. Therefore, it needs to know about the manage= ment layer via the management context. The management context allows an obj= ect implementing the ManagementAware interface to receive a context to perf= orm further registration of managed objects. + + @Managed +public class CacheServiceManaged implements ManagementAware { + + /** . */ + private ManagementContext context; + + /** . */ + private CacheServiceImpl cacheService; + + public CacheServiceManaged(CacheServiceImpl cacheService) { + this.cacheService =3D cacheService; + + // + cacheService.managed =3D this; + } + + public void setContext(ManagementContext context) { + this.context =3D context; + } + + void registerCache(ExoCache cache) { + if (context !=3D null) { + context.register(cache); + } + } +} +
+
+
Modified: epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopmen= t/DataImportStrategy.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment/Data= ImportStrategy.xml 2013-03-21 02:18:56 UTC (rev 9217) +++ epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment/Data= ImportStrategy.xml 2013-03-21 02:26:49 UTC (rev 9218) @@ -5,6 +5,7 @@ ]> Data Import Strategy + MOVED to Development Guide - Data_Import_Strategy.xml
Introduction Modified: epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopmen= t/DefaultPortalConfiguration.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment/Defa= ultPortalConfiguration.xml 2013-03-21 02:18:56 UTC (rev 9217) +++ epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment/Defa= ultPortalConfiguration.xml 2013-03-21 02:26:49 UTC (rev 9218) @@ -6,6 +6,7 @@ Default Portal Configuration Source content: https://docs.jboss.org/author/display/GTNPORTAL3= 5/Default+Portal+Configuration + MOVED: Development Guide - Default_Portal_Configuration.xml
Overview Modified: epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopmen= t/DefaultPortalNavigationConfiguration.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment/Defa= ultPortalNavigationConfiguration.xml 2013-03-21 02:18:56 UTC (rev 9217) +++ epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment/Defa= ultPortalNavigationConfiguration.xml 2013-03-21 02:26:49 UTC (rev 9218) @@ -6,6 +6,7 @@ Portal Navigation Configuration Source: https://docs.jboss.org/author/display/GTNPORTAL35/Portal= +Navigation+Configuration + MOVED to Development Guide - Portal_Navigation_Configuration.xml=
Overview Modified: epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopmen= t/DefaultPortalPermissionConfiguration.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment/Defa= ultPortalPermissionConfiguration.xml 2013-03-21 02:18:56 UTC (rev 9217) +++ epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment/Defa= ultPortalPermissionConfiguration.xml 2013-03-21 02:26:49 UTC (rev 9218) @@ -5,6 +5,7 @@ ]> Portal Default Permission Configuration + MOVED: Development Guide - Portal_Permission_Configuration.xml
Overview Modified: epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopmen= t/InternationalizationConfiguration.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment/Inte= rnationalizationConfiguration.xml 2013-03-21 02:18:56 UTC (rev 9217) +++ epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment/Inte= rnationalizationConfiguration.xml 2013-03-21 02:26:49 UTC (rev 9218) @@ -6,6 +6,7 @@ <remark>BZ#896760 </remark>Internationalization Configuration</ti= tle> <remark>Source: https://docs.jboss.org/author/display/GTNPORTAL35/Intern= ationalization+Configuration</remark> + <remark>MOVED to Development Guide - Internationalization_Configuration.= xml</remark> <section id=3D"sect-Reference_Guide-Internationalization_Configuration-O= verview"> <title>Overview Modified: epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopmen= t/JavascriptInterApplicationCommunication.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment/Java= scriptInterApplicationCommunication.xml 2013-03-21 02:18:56 UTC (rev 9217) +++ epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment/Java= scriptInterApplicationCommunication.xml 2013-03-21 02:26:49 UTC (rev 9218) @@ -4,7 +4,8 @@ %BOOK_ENTITIES; ]> - JavaScript Inter Application Communication + JavaScript Inter-application Communication + MOVED to Development Guide - Javascript_Inter-application_Commun= ication.xml
Overview Modified: epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopmen= t/LocalizationConfiguration.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment/Loca= lizationConfiguration.xml 2013-03-21 02:18:56 UTC (rev 9217) +++ epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment/Loca= lizationConfiguration.xml 2013-03-21 02:26:49 UTC (rev 9218) @@ -5,6 +5,7 @@ ]> Localization Configuration + MOVED to Development Guide - Localization_Configuration.xml
Pluggable Locale Policy Source: https://docs.jboss.org/author/display/GTNPORTAL35/Plug= gable+Locale+Policy Modified: epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopmen= t/NavigationController.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment/Navi= gationController.xml 2013-03-21 02:18:56 UTC (rev 9217) +++ epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment/Navi= gationController.xml 2013-03-21 02:26:49 UTC (rev 9218) @@ -5,6 +5,7 @@ ]> Navigation Controller + MOVED to Development Guide - Navigation_Controller.xml
Description Modified: epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopmen= t/PortalLifecycle.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment/Port= alLifecycle.xml 2013-03-21 02:18:56 UTC (rev 9217) +++ epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment/Port= alLifecycle.xml 2013-03-21 02:26:49 UTC (rev 9218) @@ -5,6 +5,7 @@ ]> Portal Life-cycle + MOVED: Chapter moved to Development Guide: Portal_Lifecycle.xml<= /remark>
Overview @@ -87,10 +88,10 @@ /gateinservlet ]]> - - - -
+ + + +
The Command Servlet Modified: epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopmen= t/RTLFramework.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment/RTLF= ramework.xml 2013-03-21 02:18:56 UTC (rev 9217) +++ epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment/RTLF= ramework.xml 2013-03-21 02:26:49 UTC (rev 9218) @@ -5,6 +5,7 @@ ]> Right To Left (RTL) Framework + MOVED to Development Guide - RTL_Framework.xml The text orientation depends on the current locale setting. The orientat= ion is a Java 5 enum that provides a set of functionalities: Modified: epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopmen= t/Skinning.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment/Skin= ning.xml 2013-03-21 02:18:56 UTC (rev 9217) +++ epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment/Skin= ning.xml 2013-03-21 02:26:49 UTC (rev 9218) @@ -5,6 +5,7 @@ ]> Skinning the Portal + MOVED: Chapter moved to Development Guide: Skinning_The_Portal.x= ml
Overview Modified: epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopmen= t/XMLResourceBundles.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment/XMLR= esourceBundles.xml 2013-03-21 02:18:56 UTC (rev 9217) +++ epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment/XMLR= esourceBundles.xml 2013-03-21 02:26:49 UTC (rev 9218) @@ -5,6 +5,7 @@ ]> XML Resources Bundles + MOVED to Development Guide - XML_Resource_Bundles.xml
Overview Modified: epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopmen= t.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment.xml = 2013-03-21 02:18:56 UTC (rev 9217) +++ epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortalDevelopment.xml = 2013-03-21 02:26:49 UTC (rev 9218) @@ -1,25 +1,20 @@ - + %BOOK_ENTITIES; ]> - Portal Development - - - - - - - - - - - - - - = - = - + Portal Development + + + + + + + + + + + + - Modified: epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortletDevelopme= nt/Global_Portlet.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortletDevelopment/Glo= bal_Portlet.xml 2013-03-21 02:18:56 UTC (rev 9217) +++ epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortletDevelopment/Glo= bal_Portlet.xml 2013-03-21 02:26:49 UTC (rev 9218) @@ -5,6 +5,7 @@ ]> Shared portlet.xml + MOVED to Development Guide - Global_Portlet.xml The Java Portlet Specification introduces PortletFilter as a standard approach to extend the behaviors of portlet objects.= For example, a filter can transform the content of portlet requests and po= rtlet responses. Modified: epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortletDevelopme= nt/PortletBridge.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortletDevelopment/Por= tletBridge.xml 2013-03-21 02:18:56 UTC (rev 9217) +++ epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortletDevelopment/Por= tletBridge.xml 2013-03-21 02:26:49 UTC (rev 9218) @@ -5,6 +5,7 @@ ]> JBoss Portlet Bridge + MOVED to Developers Guide - Portlet_Bridge.xml
Portlet Bridge A portlet bridge is a mediator that allows non-native applicatio= n frameworks to run in a portal environment, independent to the underlying = portlet API, or portlet concept. This functionality provides a developer fl= exibility to continue writing applications in a preferred language, and all= ows a controlled transition to new technologies. Modified: epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortletDevelopme= nt/Standard.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortletDevelopment/Sta= ndard.xml 2013-03-21 02:18:56 UTC (rev 9217) +++ epp/docs/JPP/trunk/Reference_Guide/en-US/modules/PortletDevelopment/Sta= ndard.xml 2013-03-21 02:26:49 UTC (rev 9218) @@ -5,6 +5,7 @@ ]> Portlet Primer + MOVED to Development Guide - Portlet_Development_Resources.xml
JSR-168 and JSR-286 overview Modified: epp/docs/JPP/trunk/Reference_Guide/en-US/modules/ServerIntegratio= n.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D (Binary files differ) --===============0725143513055394243==--