JBoss.orgCommunity Documentation

Chapter 2. Configuration

2.1. Database Configuration
2.1.1. Overview
2.1.2. Configuring the database for JCR
2.1.3. Configuring the database for the default identity store
2.2. E-Mail Service Configuration
2.2.1. Overview
2.2.2. Configuring the database for JCR
2.3. Default Portal Configuration
2.3.1. Overview
2.3.2. Configuration
2.4. PicketLink IDM integration
2.4.1. Configuration files
2.5. Portal Navigation Configuration
2.5.1. Overview
2.5.2. Portal Navigation
2.5.3. Group Navigation
2.5.4. User Navigation
2.5.5. Tips
2.6. Authentication Token Configuration
2.6.1. What is token service
2.6.2. Implement token service's API
2.6.3. Configure token services
2.7. Predefined User Configuration
2.7.1. Overview
2.7.2. Plugin for adding users, groups and membership types
2.7.3. Membership types
2.7.4. Groups
2.7.5. Users
2.7.6. Plugin for monitoring user creation
2.8. Portal Default Permission Configuration
2.8.1. Overview
2.8.2. Overwrite Portal Default Permissions
2.9. Data Injector Configuration
2.9.1. Data Injector
2.9.2. OrganizationInitializer
2.9.3. Group Parameters
2.9.4. User Parameters
2.9.5. Automatic Navigation Creation
2.10. Skin Configuration
2.10.1. Overview
2.10.2. Skin Switching
2.10.3. Types of skins
2.10.4. Skins in Page Markups
2.10.5. Set the default skin
2.10.6. How to create a new skin
2.10.7. How to create a new window style
2.10.8. How to create new Portlet skins
2.10.9. Tips and Tricks
2.11. Javascript Configuration
2.12. Dashboard configuration

To configure the database used by JCR you will need to edit the file:

$JBOSS_HOME/server/default/conf/gatein/configuration.properties

For Tomcat, the file is located at

$TOMCAT_HOME/gatein/conf/configuration.properties

And edit the values of driver, url, username and password with the values for your JDBC connection (Please refer to your database JDBC driver documentation).


gatein.jcr.datasource.driver=org.hsqldb.jdbcDriver
gatein.jcr.datasource.url=jdbc:hsqldb:file:${gatein.db.data.dir}/data/jdbcjcr_${name}
gatein.jcr.datasource.username=sa
gatein.jcr.datasource.password=

In that case, the name of the database is "jdbcjcr_${name}", ${name} should be part of the database name, as it is dynamically replaced by the name of the portal container extension (for instance gatein-sample-portal.ear defines "sample-portal" as container name and the default portal defines "portal" as container name).

In the case of HSQL the databases are created automatically, for any other database you will need to create a database named jdbcjcr_portal (and "jdbcjcr_sample-portal" if you kept gatein-sample-portal.ear in $JBOSS_HOME/server/default/deploy. Note that some database wont accept '-' in a database name and you will have to delete $JBOSS_HOME/server/default/deploy/gatein-sample-portal.ear)

Make sure the user has rights to create tables on jdbcjcr_portal and to update them as during the first startup they will be automatically created.

Also add the JDBC driver into the classpath, for instance in $JBOSS_HOME/server/default/lib (or $TOMCAT_HOME/lib if you are running on Tomcat)

MySQL example:

Let's configure our JCR to store data in MySQL, let's pretend we have a user named "gateinuser" with a password "gateinpassword". We would create a database "mygateindb_portal" (Remember that _portal is required) and assign him the rights to create tables.

Then we need to add the MySQL JDBC connector in the classpath and finally edit gatein.ear/02portal.war/WEB-INF/conf/jcr/jcr-configuration with:

gatein.jcr.datasource.driver=com.mysql.jdbc.Driver
gatein.jcr.datasource.url=jdbc:mysql://localhost:3306/mygateindb${container.name.suffix}
gatein.jcr.datasource.username=gateinuser
gatein.jcr.datasource.password=gateinpassword

GateIn 3.0 uses the PicketLink IDM component to retain necessary identity information (user, groups, memberships, etc.). While legacy interfaces are still used (org.exoplatform.services.organization) for identity management, the wrapper implementation delegates to the PicketLink IDM framework.

This section doesn't provide information about PicketLink IDM and its configuration. Please refer to the appropriate project documentation (http://jboss.org/picketlink/IDM.html) for further information.

Note

It is important to fully understand the concepts behind this framework design before changing the default configuration.

The identity model represented in 'org.exoplatform.services.organization' interfaces and the one used in PicketLink IDM have some major differences.

For example: the PicketLink IDM provides greater abstraction. It is possible for groups in the IDM framework to form memberships with many parents (which requires recursive ID translation) while the GateIn model allows only pure tree like membership structures.

Additionally the GateIn membership concept needs to be translated into the IDM Role concept. Therefore PicketLink IDM model is used in a limited way. All these translations are applied by the integration layer.

The main configuration file is idm-configuration:

<configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd http://www.exoplaform.org/xml/ns/kernel_1_0.xsd"
               xmlns="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd">
 
   <component>(1)
        <key>org.exoplatform.services.organization.idm.PicketLinkIDMService</key>
      <type>org.exoplatform.services.organization.idm.PicketLinkIDMServiceImpl</type>
      <init-params>
         <value-param>
            <name>config</name>
            <value>war:/conf/organization/idm-config.xml</value>
         </value-param>
         <value-param>
            <name>portalRealm</name>
            <value>realm${container.name.suffix}</value>
         </value-param>
       </init-params>
   </component>
 
 
   <component>
      <key>org(2).exoplatform.services.organization.OrganizationService</key>
      <type>org.exoplatform.services.organization.idm.PicketLinkIDMOrganizationServiceImpl</type>
      <init-params>
      <object-param>
        <name>configuration</name>
        <object type="org.exoplatform.services.organization.idm.Config">
          <field name="useParentIdAsGroupType">
            <boolean>true</boolean>
          </field>
 
          <field name="forceMembershipOfMappedTypes">
            <boolean>true</boolean>
          </field>
 
          <field name="pathSeparator">
            <string>.</string>
          </field>
 
          <field name="rootGroupName">
            <string>GTN_ROOT_GROUP</string>
          </field>
 
          <field name="groupTypeMappings">
            <map type="java.util.HashMap">
              <entry>
                <key><string>/</string></key>
                <value><string>root_type</string></value>
              </entry>
 
              <!-- Sample mapping -->
              <!--
              <entry>
                <key><string>/platform/*</string></key>
                <value><string>platform_type</string></value>
              </entry>
              <entry>
                <key><string>/organization/*</string></key>
                <value><string>organization_type</string></value>
              </entry>
              -->
 
            </map>
          </field>
 
          <field name="associationMembershipType">
            <string>member</string>
          </field>
 
          <field name="ignoreMappedMembershipType">
            <boolean>false</boolean>
          </field>
        </object>
      </object-param>
    </init-params>
 
 
   </component>
 
</configuration>
1

The org.exoplatform.services.organization.idm.PicketLinkIDMServiceImpl service has following options:

config

(value-param)

PicketLink IDM configuration file

hibernate.properties

(properties-param)

A list of hibernate properties used to create SessionFactory that will be injected to JBoss Identity IDM configuration registry.

hibernate.annotations

A list of annotated classes that will be added to hibernate configuration.

hibernate.mappings

A list of xml files that will be added to hibernate configuration as mapping files.

jndiName

(value-param)

If the 'config' parameter is not provided this parameter will be used to perform JNDI lookup for IdentitySessionFactory

portalRealm

(value-param)

The name of a realm that should be used to obtain proper IdentitySession. The default is 'PortalRealm'.

2

The org.exoplatform.services.organization.idm.PicketLinkIDMOrganizationServiceImpl key is a main entrypoint implementing org.exoplatform.services.organization.OrganizationService and is dependant on org.exoplatform.services.organization.idm.PicketLinkIDMService

org.exoplatform.services.organization.idm.PicketLinkIDMOrganizationServiceImpl service has following options defined as fields of object-param type org.exoplatform.services.organization.idm.Config:

defaultGroupType

The name of the PicketLink IDM GroupType that will be used to store groups. The default is 'GTN_GROUP_TYPE'.

rootGroupName

The name of the PicketLink IDM Group that will be used as a root parent. The default is 'GTN_ROOT_GROUP'

passwordAsAttribute

This parameter specifies if a password should be stored using PicketLink IDM Credential object or as a plain attribute. The default is false.

useParentIdAsGroupType

This parameter stores the parent ID path as a group type in PicketLink IDM for any IDs not mapped with a specific type in 'groupTypeMappings'. If this option is set to false and no mappings are provided under 'groupTypeMappings' only one group with a given name can exist in the GateIn 3.0 group tree.

pathSeparator

When 'userParentIdAsGroupType is set to true, this value will be used to replace all "/" characters in IDs. The "/" character is not allowed to be used in group type name in PicketLink IDM.

associationMembershipType

If this option is used then each Membership created with MembrshipType that is equal to the value specified here will be stored in PicketLink IDM as simple Group-User association.

groupTypeMappings

This parameter maps groups added with the GateIn 3.0 API as a child of a given group ID and stores them with a given group type name in PicketLink IDM.

If the parent ID ends with "/*" then all child groups will have the mapped group type. Otherwise only direct (first level) children will use this type.

This can be leveraged by LDAP if LDAP DN is configured in PicketLink IDM to only store a specific group type. This will then store the given branch in the GateIn 3.0 group tree while all other groups will remain in the database.

forceMembershipOfMappedTypes

Groups stored in PicketLink IDM with a type mapped in 'groupTypeMappings' will automatically be a member under the mapped parent. Group relationships linked by PicketLink IDM group association will not be necessary.

This parameter can be set to false if all groups are added via GateIn 3.0 APIs. This may be useful with LDAP configuration as, when set to true, it will make every entry added to LDAP appear in GateIn 3.0. This is not true for entries added via the GateIn 3.0 management UI, however.

ignoreMappedMembershipType

If "associationMembershipType" option is used and this option is set to true then Membership with MembershipType configured to be stored as PicketLink IDM association will not be stored as PicketLink IDM Role.

Additionally JBossIDMOrganizationServiceImpl uses those defaults to perform identity management operations

  • GateIn 3.0 User interface properties fields are persisted in JBoss Identity IDM using those attributes names: firstName, lastName, email, createdDate, lastLoginTime, organizationId, password (if password is configured to be stored as attribute)

  • GateIn 3.0 Group interface properties fields are persisted in JBoss Identity IDM using those attributes names: label, description

  • GateIn 3.0 MembershipType interface properties fields are persisted in JBoss Identity IDM using those RoleType properties: description, owner, create_date, modified_date

A sample PicketLink IDM configuration file is shown below. To understand all the options present in it please refer to the PicketLink IDM Reference Guide

<jboss-identity xmlns="urn:jboss:identity:idm:config:v1_0_beta"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:schemaLocation="urn:jboss:identity:idm:config:v1_0_alpha identity-config.xsd">
    <realms>
        <realm>
            <id>PortalRealm</id>
            <repository-id-ref>PortalRepository</repository-id-ref>
            <identity-type-mappings>
                <user-mapping>USER</user-mapping>
            </identity-type-mappings>
        </realm>
    </realms>
    <repositories>
        <repository>
            <id>PortalRepository</id>
            <class>org.jboss.identity.idm.impl.repository.WrapperIdentityStoreRepository</class>
            <external-config/>
            <default-identity-store-id>HibernateStore</default-identity-store-id>
            <default-attribute-store-id>HibernateStore</default-attribute-store-id>
        </repository>
    </repositories>
    <stores>
        <attribute-stores/>
        <identity-stores>
            <identity-store>
                <id>HibernateStore</id>
                <class>org.jboss.identity.idm.impl.store.hibernate.HibernateIdentityStoreImpl</class>
                <external-config/>
                <supported-relationship-types>
                    <relationship-type>JBOSS_IDENTITY_MEMBERSHIP</relationship-type>
                    <relationship-type>JBOSS_IDENTITY_ROLE</relationship-type>
                </supported-relationship-types>
                <supported-identity-object-types>
                    <identity-object-type>
                        <name>USER</name>
                        <relationships/>
                        <credentials>
                            <credential-type>PASSWORD</credential-type>
                        </credentials>
                        <attributes/>
                        <options/>
                    </identity-object-type>
                </supported-identity-object-types>
                <options>
                    <option>
                        <name>hibernateSessionFactoryRegistryName</name>
                        <value>hibernateSessionFactory</value>
                    </option>
                    <option>
                        <name>allowNotDefinedIdentityObjectTypes</name>
                        <value>true</value>
                    </option>
                    <option>
                        <name>populateRelationshipTypes</name>
                        <value>true</value>
                    </option>
                    <option>
                        <name>populateIdentityObjectTypes</name>
                        <value>true</value>
                    </option>
                    <option>
                        <name>allowNotDefinedAttributes</name>
                        <value>true</value>
                    </option>
                    <option>
                        <name>isRealmAware</name>
                        <value>true</value>
                    </option>
                </options>
            </identity-store>
        </identity-stores>
    </stores>
</jboss-identity>

Three types of navigation are available to portal users:

These navigations are configured with standard XML syntax in the file; "02portal.war:/WEB-INF/conf/portal/portal-configuration.xml".


<component>
  <key>org.exoplatform.portal.config.UserPortalConfigService</key>
  <type>org.exoplatform.portal.config.UserPortalConfigService</type>
  <component-plugins>           
   <component-plugin>
     <name>new.portal.config.user.listener</name>
     <set-method>initListener</set-method>
     <type>org.exoplatform.portal.config.NewPortalConfigListener</type>
     <description>this listener init the portal configuration</description>
     <init-params>
       <value-param>
         <name>default.portal</name>
         <description>The default portal for checking db is empty or not</description>
         <value>classic</value>
       </value-param> 
       <object-param>
         <name>portal.configuration</name>
         <description>description</description>
         <object type="org.exoplatform.portal.config.NewPortalConfig">
           <field  name="predefinedOwner">
             <collection type="java.util.HashSet">                
               <value><string>classic</string></value>
               <value><string>webos</string></value>
             </collection>
           </field>
           <field  name="ownerType"><string>portal</string></field>
           <field  name="templateLocation"><string>war:/conf/portal</string></field> 
         </object>
       </object-param> 
       <object-param>
         <name>group.configuration</name>
         <description>description</description>
         <object type="org.exoplatform.portal.config.NewPortalConfig">
           <field  name="predefinedOwner">
             <collection type="java.util.HashSet">            
              <value><string>platform/administrators</string></value>    
              <value><string>platform/users</string></value>
              <value><string>platform/guests</string></value>
              <value><string>organization/management/executive-board</string></value>               
             </collection>
           </field>
           <field  name="ownerType"><string>group</string></field>
           <field  name="templateLocation"><string>war:/conf/portal</string></field> 
         </object>
       </object-param>       
       <object-param>
         <name>user.configuration</name>
         <description>description</description>
         <object type="org.exoplatform.portal.config.NewPortalConfig">
           <field  name="predefinedOwner">
             <collection type="java.util.HashSet">                
               <value><string>root</string></value>
               <value><string>john</string></value>
               <value><string>mary</string></value>
               <value><string>demo</string></value>
             </collection>
           </field>
           <field  name="ownerType"><string>user</string></field>
           <field  name="templateLocation"><string>war:/conf/portal</string></field> 
         </object>
       </object-param>
     </init-params>
   </component-plugin>
</component-plugins>

This XML file defines, for the three navigations, which sets of portals, groups or users will have XML files inside the apprpriate war. Those files will be used to create an initial navigation the first time the portal is launched. That information will then be stored in the JCR and is then modifiable from the portal UI.

The portal navigation incorporates the pages that can be accessed when the user is not logged in (if the applicable permissions allow public access). For example; several portal navigations are used when a company has multiple trademarks and each trade has its own website.

The classic portal is configured by four XML files in the 02portal.war:/WEB-INF/conf/portal/portal/classic directory:

Portal.xml

This file describes the layout and portlets that will be shown on all pages. Usually the layout contains the banner, footer, menu and breadcrumbs portlets. GateIn 3.0 is extremely configurable as every area (even the banner and footer) is a portlet.


<?xml version="1.0" encoding="ISO-8859-1"?>
<portal-config>
  <portal-name>classic</portal-name>
  <locale>en</locale>
  <factory-id>office</factory-id>
  <access-permissions>Everyone</access-permissions>
  <edit-permission>*:/platform/administrators</edit-permission>
  <creator>root</creator>    
    
  <portal-layout>   
  <application>
     <instance-id>portal#classic:/web/BannerPortlet/banner</instance-id>
     <show-info-bar>false</show-info-bar>
   </application>
   <application>
    <instance-id>portal#classic:/web/NavigationPortlet/toolbar</instance-id>
     <show-info-bar>false</show-info-bar>
   </application>
  
   <application>
     <instance-id>portal#classic:/web/BreadcumbsPortlet/breadcumbs</instance-id>
     <show-info-bar>false</show-info-bar>
   </application>
   
 
   <page-body> </page-body>
   
   <application>
     <instance-id>portal#classic:/web/FooterPortlet/footer</instance-id>
     <show-info-bar>false</show-info-bar>
   </application>
  </portal-layout>
  
</portal-config>

It is also possible to apply a nested container that can also contain portlets. Row, column or tab containers are then responsible of the layout of their child portlets.

Each application references a portlet using the id portal#{portalName}:/{portletWarName}/{portletName}/{uniqueId}

Use the page-body tag to define where GateIn 3.0 should render the current page.

The defined classic portal is accessible to "Everyone" (at /portal/public/classic) but only members of the group /platform/administrators can edit it.

Navigation.xml

This file defines all the navigation nodes the portal will have. The syntax is simple, using nested node tags. Each node references a page that is defined in the next XML file.

If the label #{} node label is used, the internationalization mechanism is activated and the actual label to render is taken from an associated properties file for the current locale.


<?xml version="1.0" encoding="UTF-8"?>
<node-navigation>
  <owner-type>portal</owner-type>
  <owner-id>classic</owner-id>
  <priority>1</priority>
  <page-nodes>
   <node>
     <uri>home</uri>
     <name>home</name>
     <label>#{portal.classic.home}</label>
     <page-reference>portal::classic::homepage</page-reference>     
   </node>    
   <node>
     <uri>webexplorer</uri>
     <name>webexplorer</name>
     <label>#{portal.classic.webexplorer}</label>
     <page-reference>portal::classic::webexplorer</page-reference>     
   </node>
  </page-nodes>
</node-navigation>

This navigation tree can have multiple views inside portlets (such as the breadcrumbs portlet) that render the current view node, the site map or the menu portlets.

Pages.xml

This XML file structure is very similar to portal.xml and it can also contain container tags. Each application can decide whether to render the portlet border, the window state icons or the mode.


<?xml version="1.0" encoding="ISO-8859-1"?>
<page-set>  
  <page>
    <page-id>portal::classic::homepage</page-id>
    <owner-type>portal</owner-type>
    <owner-id>classic</owner-id>
    <name>homepage</name>
    <title>Home Page</title>
    <access-permissions>Everyone</access-permissions>
    <edit-permission>*:/platform/administrators</edit-permission>
    <application>
      <instance-id>portal#classic:/web/HomePagePortlet/homepageportlet</instance-id>
      <title>Home Page portlet</title>
      <show-info-bar>false</show-info-bar>
      <show-application-state>false</show-application-state>
      <show-application-mode>false</show-application-mode>
    </application>
  </page>    
    
  <page>
    <page-id>portal::classic::webexplorer</page-id>
    <owner-type>portal</owner-type>
    <owner-id>classic</owner-id>
    <name>webexplorer</name>
    <title>Web Explorer</title>
    <access-permissions>*:/platform/users</access-permissions>
    <edit-permission>*:/platform/administrators</edit-permission>    
    <application>
      <instance-id>group#platform/users:/web/BrowserPortlet/WebExplorer</instance-id>
      <title>Web Explorer</title>
      <show-info-bar>false</show-info-bar>
    </application>  
  </page>  
</page-set>
Portlet-preferences.xml

Porlet instances can be associated with portlet-preferences that override the one defined in portlet.xml file of the portlet application war .


<?xml version="1.0" encoding="ISO-8859-1"?>
<portlet-preferences-set>
  <portlet-preferences>
    <owner-type>portal</owner-type>
    <owner-id>classic</owner-id>
    <window-id>portal#classic:/web/BannerPortlet/banner</window-id>
    <preference>
      <name>template</name>
      <value>par:/groovy/groovy/webui/component/UIBannerPortlet.gtmpl</value>
      <read-only>false</read-only>
    </preference>
  </portlet-preferences>
  <portlet-preferences>
    <owner-type>portal</owner-type>
    <owner-id>classic</owner-id>
    <window-id>portal#classic:/web/NavigationPortlet/toolbar</window-id>
    <preference>
      <name>useAJAX</name>
      <value>true</value>
      <read-only>false</read-only>
    </preference>
  </portlet-preferences>
  <portlet-preferences>
    <owner-type>portal</owner-type>
    <owner-id>classic</owner-id>
    <window-id>portal#classic:/web/FooterPortlet/footer</window-id>
    <preference>
      <name>template</name>
      <value>par:/groovy/groovy/webui/component/UIFooterPortlet.gtmpl</value>
      <read-only>false</read-only>
    </preference>
  </portlet-preferences>
  
  
  <portlet-preferences>
    <owner-type>portal</owner-type>
    <owner-id>classic</owner-id>
    <window-id>portal#classic:/web/GroovyPortlet/groovyportlet</window-id>
    <preference>
      <name>template</name>
      <value>par:/groovy/groovy/webui/component/UIGroovyPortlet.gtmpl</value>
      <read-only>false</read-only>
    </preference>
  </portlet-preferences>
</portlet-preferences-set>

The user navigation is the set of nodes and pages that are owned by a user. They are part of the user dashboard.

Three files configure the user navigation (navigation.xml, pages.xml and portlet-preferences.xml). They are located in the directory "portal/WEB-INF/conf/portal/users/{userName}".

This directory also contains a gadgets.xml file (which was formerly called widgets.xml). This file defines the gadgets located in the user workspace.

The user workspace is located at the left hand side of the page and access is restricted to some privileged users, see Section 2.7, “Predefined User Configuration”


<?xml version="1.0" encoding="ISO-8859-1"?>
<widgets>
  <owner-type>user</owner-type>
  <owner-id>root</owner-id>
 
  <container id="Information">
    <name>Information</name>
    <description>Information's Description</description>
    <application>
      <instance-id>user#root:/GateInWidgetWeb/WelcomeWidget/WelcomeWidget1</instance-id>
      <application-type>GateInWidget</application-type>
    </application>
      
    <application>
      <instance-id>user#root:/GateInWidgetWeb/StickerWidget/StickerWidget</instance-id>
      <application-type>GateInWidget</application-type> 
    </application>
    
    <application>
      <instance-id>user#root:/GateInWidgetWeb/InfoWidget/InfoWidget1</instance-id>
      <application-type>GateInWidget</application-type>
    </application>
  </container>
  
  <container id="Calendar">
    <name>Calendar</name>
    <description>Calendar's Description</description>
    <application>
      <instance-id>user#root:/GateInWidgetWeb/CalendarWidget/CalendarWidget</instance-id>
      <application-type>GateInWidget</application-type> 
    </application>
  </container> 
 
</widgets>

The plugin of type org.exoplatform.services.organization.impl.NewUserEventListener specifies which groups should join all newly created users. It notably specifies the groups and memberships to be used. It also specifies a list of users that should be excepted.


<component-plugin>
  <name>new.user.event.listener</name>
  <set-method>addListenerPlugin</set-method>
  <type>org.exoplatform.services.organization.impl.NewUserEventListener</type>
  <description>this listener assign group and membership to a new created user</description>
  <init-params>
    <object-param>
      <name>configuration</name>
      <description>description</description>
      <object type="org.exoplatform.services.organization.impl.NewUserConfig">
        <field  name="group">
          <collection type="java.util.ArrayList">
            <value>
              <object type="org.exoplatform.services.organization.impl.NewUserConfig$JoinGroup">
                <field name="groupId"><string>/user</string></field>
                <field name="membership"><string>member</string></field>
              </object>
            </value>               
          </collection>
        </field>
        <field  name="ignoredUser">
          <collection type="java.util.HashSet">
            <value><string>exo</string></value>
            <value><string>root</string></value>
            <value><string>company</string></value>
            <value><string>community</string></value>
          </collection>
        </field>
      </object>
    </object-param>
  </init-params>
</component-plugin>

The permission configuration for the portal is defined in the file 02portal.war:/WEB-INF/conf/portal/portal-configuration.xml . The component UserACL is described there along with other portal component configurations.

It defines 5 permissions types:


<component>
  <key>org.exoplatform.portal.config.UserACL</key>
  <type>org.exoplatform.portal.config.UserACL</type>   
  <init-params>      
    <value-param>
      <name>super.user</name>
      <description>administrator</description>
      <value>root</value>     
    </value-param>
      
    <value-param>
      <name>portal.creator.groups</name>
      <description>groups with membership type have permission to manage portal</description>
      <value>*:/platform/administrators,*:/organization/management/executive-board</value>     
    </value-param>
      
    <value-param>
      <name>navigation.creator.membership.type</name>
      <description>specific membership type have full permission with group navigation</description>
      <value>manager</value>     
    </value-param>
    <value-param>
      <name>guests.group</name>
      <description>guests group</description>
      <value>/platform/guests</value>     
    </value-param>     
    <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>           
  </init-params>   
</component>

OrganizationInitializer is the service that allows creating a large organization with many groups and users. It also creates portal navigation and page(s) for each group and each user.

Service configuration file

<configuration>
  <component>
  <key>org.exoplatform.portal.initializer.organization.OrganizationInitializer</key>
  <type>org.exoplatform.portal.initializer.organization.OrganizationInitializer</type>
    <init-params>
      <value-param>
        <name>auto.create.group.page.navigation</name>
        <description>true or false</description>
        <value>true</value>
      </value-param>
       
      <value-param>
        <name>auto.create.user.page.navigation</name>
        <description>number of pages per user</description>
        <value>10</value>
      </value-param>
      
      <object-param>
        <name>organization</name>
        <description>description</description>
        <object type="org.exoplatform.portal.initializer.organization.OrganizationConfig">
          <field name="groups">
            <collection type="java.util.ArrayList">
              <value>
                <object type="org.exoplatform.portal.initializer.organization.OrganizationConfig$GroupsConfig">
                  <field name="group">
                    <object type="org.exoplatform.services.organization.OrganizationConfig$Group">
                      <field name="name"><string>province</string></field>
                      <field name="parentId"><string>/africa/tanzania</string></field>
                      <field name="description"><string>Tanzania's province</string></field>
                      <field name="label"><string>Province</string></field>
                    </object>                
                  </field> 
                  <field name="from"><string>1</string></field>
                  <field name="to"><string>10</string></field>
                </object>
              </value>
            </collection>
          </field>
          <field name="users">
            <collection type="java.util.ArrayList"> 
              <value>
                <object type="org.exoplatform.portal.initializer.organization.OrganizationConfig$UsersConfig">
                  <field name="user">
                    <object type="org.exoplatform.services.organization.OrganizationConfig$User">
                      <field name="userName"><string>user</string></field>
                      <field name="password"><string>GateInPlatform</string></field>
                      <field name="firstName"><string>First-Name</string></field>
                      <field name="lastName"><string>Last-Name</string></field>
                      <field name="email"><string>exo@localhost</string></field>
                      <field name="groups"><string>member:/africa</string></field>
                    </object>
                  </field>
                  <field name="from"><string>0</string></field>
                  <field name="to"><string>9</string></field>
                </object>
              </value>
            </collection>
          </field>
        </object>
      </object-param>
    </init-params>
  </component>  
</configuration>

Window styles are the CSS applied to window decoration. When an administrator choose a new application to add on a page he can decide which style of decoration would go around the window if any.

The code below illustrates the inclusion of all CSS resoucres for a new theme from the example file GateInResourcesCp060508/skin/MyPortalSkin/PortletThemes/Stylesheet.css.

/*---- MyTheme ----*/
.MyTheme .WindowBarCenter .WindowPortletInfo {
  margin-right: 80px; /* orientation=lt */
  margin-left: 80px; /* orientation=rt */
}
.MyTheme .WindowBarCenter .ControlIcon {
  float: right;/* orientation=lt */
  float: left;/* orientation=rt */
  width: 24px; 
  height: 17px;
  cursor: pointer;
  background-image: url('background/MyTheme.png');
}
.MyTheme .ArrowDownIcon {
  background-position: center 20px;
}
.MyTheme .OverArrowDownIcon {
  background-position: center 116px;
}
.MyTheme .MinimizedIcon {
  background-position: center 44px;
}
.MyTheme .OverMinimizedIcon {
  background-position: center 140px;
}
.MyTheme .MaximizedIcon {
  background-position: center 68px;
}
.MyTheme .OverMaximizedIcon {
  background-position: center 164px;
}
.MyTheme .RestoreIcon {
  background-position: center 92px;
}
.MyTheme .OverRestoreIcon {
  background-position: center 188px;
}
.MyTheme .NormalIcon {
  background-position: center 92px;
}
.MyTheme .OverNormalIcon {
  background-position: center 188px;
}
.UIPageDesktop .MyTheme .ResizeArea {
  float: right;/* orientation=lt */
  float: left;/* orientation=rt */
  width: 18px; height: 18px;
  cursor: nw-resize;
  background: url('background/ResizeArea18x18.gif') no-repeat left top; /* orientation=lt */
  background: url('background/ResizeArea18x18-rt.gif') no-repeat right top; /* orientation=rt */
}
.MyTheme .Information {
  height: 18px; line-height: 18px;
  vertical-align: middle; font-size: 10px;
  padding-left: 5px;/* orientation=lt */
  padding-right: 5px;/* orientation=rt */
  margin-right: 18px;/* orientation=lt */
  margin-left: 18px;/* orientation=rt */
}
.MyTheme .WindowBarCenter .WindowPortletIcon {
  background-position: left top; /* orientation=lt */
  background-position: right top; /* orientation=rt */
  padding-left: 20px; /* orientation=lt */
  padding-right: 20px; /* orientation=rt */
  height: 16px;
  line-height: 16px;
}
.MyTheme .WindowBarCenter .PortletName {
  font-weight: bold;
  color: #333333;
  overflow: hidden;
  white-space: nowrap;
  width: 100%;
}
.MyTheme .WindowBarLeft {
  padding-left: 12px;
  background-image: url('background/MyTheme.png');
  background-repeat: no-repeat;
  background-position: left -148px;
}
.MyTheme .WindowBarRight {
  padding-right: 11px;
  background-image: url('background/MyTheme.png');
  background-repeat: no-repeat;
  background-position: right -119px;
}
.MyTheme .WindowBarCenter {
  background-image: url('background/MyTheme.png');
  background-repeat: repeat-x;
  background-position: left -90px;
}
.MyTheme .WindowBarCenter .FixHeight {
  height: 21px;
  padding-top: 8px;
}
.MyTheme .MiddleDecoratorLeft {
  padding-left: 12px;
  background: url('background/MyTheme.png') repeat-y left;
}
.MyTheme .MiddleDecoratorRight {
  padding-right: 11px;
  background: url('background/MyTheme.png') repeat-y right;
}
.MyTheme .MiddleDecoratorCenter {
  background: #ffffff;
}
.MyTheme .BottomDecoratorLeft {
  MyTheme: 12px;
  background-image: url('background/MyTheme.png');
  background-repeat: no-repeat;
  background-position: left -60px;
}
.MyTheme .BottomDecoratorRight {
  padding-right: 11px;
  background-image: url('background/MyTheme.png');
  background-repeat: no-repeat;
  background-position: right -30px;
}
.MyTheme .BottomDecoratorCenter {
  background-image: url('background/MyTheme.png');
  background-repeat: repeat-x;
  background-position: left top;
}
.MyTheme .BottomDecoratorCenter .FixHeight {
  height: 30px;
}

It is recommended that users have some experience with CSS before studying GateIn 3.0 CSS.

GateIn 3.0 relies heavily on CSS to create the layout and effects for the UI. Some common techniques for customizing GateIn 3.0's CSS are explained below.

Managing Javascript scripts in an application like GateIn 3.0 is a critical part of the configuration work. Configuring the scripts correctly will result in a faster response time from the portal.

Every portlet can have its own javscript code but in many cases it is more convenient to reuse some existing shared libraries. For that reason, GateIn 3.0 has a mechanism to easily register the libraries that will be loaded when the first page will be rendered.

To do so, every WAR deployed in GateIn 3.0 can register the js files with the groovy script "WEB-INF/conf/script/groovy/JavascriptScript.groovy".

The example file below is found in the 01eXoResources.war

JavascriptService.addJavascript("eXo", "/javascript/eXo.js", ServletContext);
/* Animation Javascripts */
JavascriptService.addJavascript("eXo.animation.ImplodeExplode", "/javascript/eXo/animation/ImplodeExplode.js", ServletContext);
/* Application descriptor */
JavascriptService.addJavascript("eXo.application.ApplicationDescriptor", "/javascript/eXo/application/ApplicationDescriptor.js", ServletContext);
/* CORE Javascripts */
JavascriptService.addJavascript("eXo.core.Utils", "/javascript/eXo/core/Util.js", ServletContext);
JavascriptService.addJavascript("eXo.core.DOMUtil", "/javascript/eXo/core/DOMUtil.js", ServletContext);
JavascriptService.addJavascript("eXo.core.Browser", "/javascript/eXo/core/Browser.js", ServletContext);
JavascriptService.addJavascript("eXo.core.MouseEventManager", "/javascript/eXo/core/MouseEventManager.js", ServletContext);
JavascriptService.addJavascript("eXo.core.UIMaskLayer", "/javascript/eXo/core/UIMaskLayer.js", ServletContext);
JavascriptService.addJavascript("eXo.core.Skin", "/javascript/eXo/core/Skin.js", ServletContext);
JavascriptService.addJavascript("eXo.core.DragDrop", "/javascript/eXo/core/DragDrop.js", ServletContext);
JavascriptService.addJavascript("eXo.core.TemplateEngine", "/javascript/eXo/core/TemplateEngine.js", ServletContext);
/* Widget Javascripts */
JavascriptService.addJavascript("eXo.widget.UIWidget", "/javascript/eXo/widget/UIWidget.js", ServletContext);
JavascriptService.addJavascript("eXo.widget.UIAddWidget", "/javascript/eXo/widget/UIAddWidget.js", ServletContext);
JavascriptService.addJavascript("eXo.widget.UIExoWidget", "/javascript/eXo/widget/UIExoWidget.js", ServletContext);
/* Desktop Javascripts */
JavascriptService.addJavascript("eXo.desktop.UIDockbar", "/javascript/eXo/desktop/UIDockbar.js", ServletContext);
JavascriptService.addJavascript("eXo.desktop.UIDesktop", "/javascript/eXo/desktop/UIDesktop.js", ServletContext);
/* WebUI Javascripts */ 
JavascriptService.addJavascript("eXo.webui.UIItemSelector", "/javascript/eXo/webui/UIItemSelector.js", ServletContext);
JavascriptService.addJavascript("eXo.webui.UIForm", "/javascript/eXo/webui/UIForm.js", ServletContext);
JavascriptService.addJavascript("eXo.webui.UIPopup", "/javascript/eXo/webui/UIPopup.js", ServletContext);
JavascriptService.addJavascript("eXo.webui.UIPopupSelectCategory", "/javascript/eXo/webui/UIPopupSelectCategory.js", ServletContext);
JavascriptService.addJavascript("eXo.webui.UIPopupWindow", "/javascript/eXo/webui/UIPopupWindow.js", ServletContext);
JavascriptService.addJavascript("eXo.webui.UIVerticalScroller", "/javascript/eXo/webui/UIVerticalScroller.js", ServletContext);
JavascriptService.addJavascript("eXo.webui.UIHorizontalTabs", "/javascript/eXo/webui/UIHorizontalTabs.js", ServletContext);
JavascriptService.addJavascript("eXo.webui.UIPopupMenu", "/javascript/eXo/webui/UIPopupMenu.js", ServletContext);
JavascriptService.addJavascript("eXo.webui.UIDropDownControl", "/javascript/eXo/webui/UIDropDownControl.js", ServletContext);
/* Portal Javascripts */ 
JavascriptService.addJavascript("eXo.portal.PortalHttpRequest", "/javascript/eXo/portal/PortalHttpRequest.js", ServletContext);
JavascriptService.addJavascript("eXo.portal.UIPortal", "/javascript/eXo/portal/UIPortal.js", ServletContext);
JavascriptService.addJavascript("eXo.portal.UIWorkspace", "/javascript/eXo/portal/UIWorkspace.js", ServletContext);
JavascriptService.addJavascript("eXo.portal.UIPortalControl", "/javascript/eXo/portal/UIPortalControl.js", ServletContext);
JavascriptService.addJavascript("eXo.portal.PortalDragDrop", "/javascript/eXo/portal/PortalDragDrop.js", ServletContext);
JavascriptService.addJavascript("eXo.portal.UIPortalNavigation", "/javascript/eXo/portal/UIPortalNavigation.js", ServletContext);
JavascriptService.addJavascript("eXo.portal.UIMaskWorkspace", "/javascript/eXo/portal/UIMaskWorkspace.js", ServletContext);
JavascriptService.addJavascript("eXo.portal.UIExoStartMenu", "/javascript/eXo/portal/UIExoStartMenu.js", ServletContext);
/* Desktop Javascripts 2 */
JavascriptService.addJavascript("eXo.desktop.UIWindow", "/javascript/eXo/desktop/UIWindow.js", ServletContext);

Note that even registered dedicated javascripts will be merged into a single merged.js file when the server loads. This reduces the number of HTTP calls as seen in the home page source code:

<script type="text/javascript" src="/portal/javascript/merged.js"></script>

Although this optimization is useful for a production environment, it may be easier to deactivate this optimization while debugging javascript problems.

To do this, set the java system property exo.product.developing to true.

To see or use the merged file set this property to false.

The property can be passed as a JVM parameter with the -D option in your GateIn.sh or GateIn.bat startup script.

Every javascript file is referenced with a module name of "eXo.core.DragDrop" which acts as a namespace. Inside the associated files, global javascript functions are used following the same namespace convention:

eXo.core.DragDrop = new DragDrop() ;

It is also possible to use the eXo.require() javascript method to lazy load and evaluate some javascript code. This is quite useful from the portlet or widget applications that will use this javascript only once. Otherwise, if the library is reusable in several places it is better to reference it in the groovy file.

The following parameters are available controll the Dashboard configuration (when in edit mode):

owner

isPrivate