{note}
This section aims at helping readers further understand about the eXo architecture, including Kernel, GateIn extensions and Java Content Repository via concepts, services, configuration, and more.
{note}

h1. Kernel {anchor:id=DEV.eXoArchitecturePremer.Kernel}

All eXo Platform services are built around the eXo Kernel, or the service management layer, which manages the configuration and the execution of all components.
The main kernel object is the eXo Container, a micro-container that glues services together through the dependency injection. The container is responsible for loading services/components.

This part introduces concepts of *Container* and *Services* with an overview before configuring basic services.

h2. Containers {anchor:id=DEV.eXoArchitecturePremer.Containers}

A container is always required to access a service, because the eXo Kernel relies on the dependency injection. This means that the lifecycle of a service (for example, instantiating, opening and closing streams, disposing) is handled by a dependency provider, such as the eXo Container, rather than the consumer. The consumer only needs a reference to an implementation of the requested service. The implementation is configured in an _.xml_ configuration file that comes with every service. To learn more about the dependency injection, visit [here|http://en.wikipedia.org/wiki/Dependency_injection].

eXo Platform provides two types of containers: RootContainer and PortalContainer.

The _RootContainer_ holds the low level components. It is automatically started before the _PortalContainer_. You will rarely interact directly with the _RootContainer_ except when you activate your own extension.
The _PortalContainer_ is created for each portal (one or several portals). All services started by this container will run as embedded in the portal. It also gives access to components of its parent _RootContainer_.

In your code, if you need to invoke a service of a container, you can use the _ExoContainerContext_ helper from any location. The code below shows you a utility method that you can use to invoke any eXo Platform services.

{code:java}
public class ExoUtils {
  /**
  * Get a service from the portal container
  * @param type : component type
  * @return the concrete instance retrieved in the container using the type as key
  */
  public <T>T getService(Class<T> type) {
    return (T)ExoContainerContext.getCurrentContainer().getComponentInstanceOfType(type);
  }
}
{code}

Then, invoking becomes as easy as:

{code:java}
OrganizationService orgService = ExoUtils.getService(OrganizationService.class)
{code}

h2. Services {anchor:id=DEV.eXoArchitecturePremer.Services}

Containers are used to gain access to services. The followings are important characteristics of services:

* Because of the Dependency Injection concept, the interface and implementation for a service are usually separate.
* Each service has to be implemented as a singleton, which means it is created only once per portal container in a single instance.
* A component equals a service. A service must not be a large application. A service can be a little component that reads or transforms a document where the term "component" is often used instead of service.

For example, in the _/lib_ folder, you can find services for the following databases, caching, and LDAP:

* exo.core.component.database-x.y.z.jar
* exo.kernel.component.cache-x.y.z.jar
* exo.core.component.organization.ldap-x.y.z.jar

h2. Service configuration {anchor:id=DEV.eXoArchitecturePremer.ServiceConfiguration}

To declare a service, you must add the *.xml* configuration file to a specific place. This file can be in the jar file, in a webapp or in the external configuration directory. If you write a new component for the eXo Container, you should always provide a default configuration in your jar file. This default configuration must be in the /conf/portal/configuration.xml file in your jar.

A configuration file can specify several services, so there can be several services in one jar file.

This section is divided into the following sub-topics:
* [Kernel XML Schema|#DEV.eXoArchitecturePremer.KernalXMLSchema]
* [Components|#DEV.eXoArchitecturePremer.Components]
* [Parameters|#DEV.eXoArchitecturePremer.Parameters]
h3. Kernel XML Schema {anchor:id=DEV.eXoArchitecturePremer.KernalXMLSchema}

Containers configuration files must comply with the kernel configuration grammar. Thus, all configurations will contain an XSD declaration like this:

{code:xml}
<configuration
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.exoplatform.org/xml/ns/kernel_1_1.xsd http://www.exoplatform.org/xml/ns/kernel_1_1.xsd"
  xmlns="http://www.exoplatform.org/xml/ns/kernel_1_1.xsd">
</configuration>
{code}

The _kernel\_1\_1.xsd_ file mentioned in the example above can be found inside {{exo.kernel.container-x.y.z.jar!org/exoplatform/container/configuration/}} along with other versions.

h3. Components {anchor:id=DEV.eXoArchitecturePremer.Components}

The service registration within the container is done with the <component> element.

For example, open the _/webapps/exo-wcm-core/WEB-INF/conf/wcm-core/core-services-configuration.xml_. You will see the following code:

{code:xml}
    <component>
        <key>org.exoplatform.services.cms.CmsService</key>
        <type>org.exoplatform.services.cms.impl.CmsServiceImpl</type>
    </component>

{code}

Each component has a _key_ which matches with the qualified Java interface name (_org.exoplatform.services.cms.CmsService_).

The specific implementation class of the component (CmsServiceImpl) is defined in the <type> tag.

If a service does not have a separate interface, the <type> will be used as the key in the container. This is the case of _ContentInitializerService_.

h3. Parameters {anchor:id=DEV.eXoArchitecturePremer.Parameters}

You can provide initial parameters for your service by defining them in the configuration file. The followings are different parameters:

* [Value-param|#DEV.eXoArchitecturePremer.Value-param]
* [Object-param|#DEV.eXoArchitecturePremer.Object-param]
* Properties-param
* [Rest of parameter types|#DEV.eXoArchitecturePremer.RestOfParameterTypes]

h4. Value-param {anchor:id=DEV.eXoArchitecturePremer.Value-param}

You can use the value-param to pass a single value to the service.

{code:xml}
<component>
  <key>org.exoplatform.services.resources.LocaleConfigService</key>
  <type>org.exoplatform.services.resources.impl.LocaleConfigServiceImpl</type>
  <init-params>
    <value-param>
      <name>locale.config.file</name>
      <value>war:/conf/common/locales-config.xml</value>
    </value-param>
  </init-params>
</component>
{code}

The _LocaleConfigService_ service accesses the value of value-param in its constructor.

{code:java}
package org.exoplatform.services.resources.impl;
public class LocaleConfigServiceImpl implements LocaleConfigService {
  public LocaleConfigServiceImpl(InitParams params, ConfigurationManager cmanager) throws Exception {
    configs_ = new HashMap<String, LocaleConfig>(10);
    String confResource = params.getValueParam("locale.config.file").getValue();
    InputStream is = cmanager.getInputStream(confResource);
    parseConfiguration(is);
  }
}
{code}

h4. Object-param {anchor:id=DEV.eXoArchitecturePremer.Object-param}

For the object-param component, you can look at the LDAP service:

{code:xml}
<component>
  <key>org.exoplatform.services.ldap.LDAPService</key>
  <type>org.exoplatform.services.ldap.impl.LDAPServiceImpl</type>
  <init-params>
    <object-param>
      <name>ldap.config</name>
      <description>Default ldap config</description>
      <object type="org.exoplatform.services.ldap.impl.LDAPConnectionConfig">
        <field name="providerURL"><string>ldaps://10.0.0.3:636</string></field>
        <field name="rootdn"><string>CN=Administrator,CN=Users,DC=exoplatform,DC=org</string></field>
        <field name="password"><string>exo</string></field>
        <field name="version"><string>3</string></field>
        <field name="minConnection"><int>5</int></field>
        <field name="maxConnection"><int>10</int></field>
        <field name="referralMode"><string>ignore</string></field>
        <field name="serverName"><string>active.directory</string></field>
      </object>
    </object-param>
  </init-params>
</component>
{code}

The object-param is used to create an object (which is actually a Java Bean) passed as a parameter to the service. This object-param is defined by a name, a description and exactly one object. The object tag defines the type of the object, while the field tags define parameters for that object.

You can see how the service accesses the object in the code below:

{code:java}
package org.exoplatform.services.ldap.impl;

public class LDAPServiceImpl implements LDAPService {
  // ...
  public LDAPServiceImpl(InitParams params) {
    LDAPConnectionConfig config = (LDAPConnectionConfig) params.getObjectParam("ldap.config").getObject();
    ...
  }
  // ...
}
{code}

The passed object is _LDAPConnectionConfig_, which is a classic Java Bean. It contains all fields defined in the configuration files and also the appropriate getters and setters (not listed here). You also can provide default values. The container creates a new instance of your Java Bean and calls all setters whose values are configured in the configuration file.

{code:java}
package org.exoplatform.services.ldap.impl;

public class LDAPConnectionConfig {
  private String providerURL = "ldap://127.0.0.1:389";
  private String rootdn;
  private String password;
  private String version;
  private String authenticationType = "simple";
  private String serverName = "default";
  private int minConnection;
  private int maxConnection;
  private String referralMode = "follow";
  // ...
}
{code}

h4. Rest of parameter types {anchor:id=DEV.eXoArchitecturePremer.RestOfParameterTypes}

Other possible parameter types are Collection, Map and Native Array. See the exhaustive reference in the Kernel reference guide.

h2. Plugins {anchor:id=DEV.eXoArchitecturePremer.Plugins}

Some components may want to offer some extensibilities. For this, they use a plugin mechanism based on the injection method. To offer an extension point for plugins, a component needs to provide a public method that takes an instance of _org.exoplatform.container.xml.
ComponentPlugin_ as a parameter.

Plugins enable you to provide the structured configuration outside the original declaration of the component. This is the main way to customize eXo Platform to your needs.

You can have a look at the configuration of the TaxonomyPlugin of the TaxonomyService as below:

{code:xml}
<external-component-plugins>
  <target-component>org.exoplatform.services.cms.taxonomy.TaxonomyService</target-component>
  <component-plugin>
    <name>predefinedTaxonomyPlugin</name>
    <set-method>addTaxonomyPlugin</set-method>
    <type>org.exoplatform.services.cms.taxonomy.impl.TaxonomyPlugin</type>
    <init-params><!-- ... --></init-params>
  </component-plugin>
</external-component-plugins>
{code}

The <target-component> defines components that host the extension point. The configuration is injected by the container using the method defined in <set-method> (addTaxonomyPlugin(). The method accepts exactly one argument of the _org.exoplatform.services.
cms.categories.impl.TaxonomyPlugin_ type.

The content of <init-params> is interpreted by the TaxonomyPlugin object.

h2. Configuration loading sequence {anchor:id=ADM.eXoArchitecturePremer.ConfigureLoadingSequence}

The Kernel startup follows a well-defined sequence to load configuration files. The objects are initialized in the container only after the whole loading sequence is done. Hence, by placing your configuration in the upper location of the sequence, you can override a component declaration by yourself. You will typically do this when you want to provide your own implementation of a component, or declare custom init-params.

{note}
The _external-component-plugins_ declarations are additive, so it is NOT possible to override them.
{note}

Configurations for the _RootContainer_ are loaded first, and then for the _PortalContainers_.

* Services default RootContainer configurations from JAR files: _/conf/configuration.xml_.
* External RootContainer configuration will be found at _$exo.conf.dir/configuration.xml_.
* Services default PortalContainer configurations from JAR files: _/conf/$PORTAL/configuration.xml_.
* Web applications configurations from WAR files _/WEB-INF/conf/configuration.xml_.
* External configuration for services of the portal will be found at _$exo.conf.dir/portal/$PORTAL/configuration.xml_.

{note}
* _$exo.conf.dir_ is a system property which points to the folder containing external configuration files on the file system. It is passed to the JVM in the startup script like _-Dexo.conf.dir=gatein_.
* _$PORTAL_ is the name of the portal container. By default, the name "portal" is unique.
{note}

h1. GateIn extensions {anchor:id=DEV.eXoArchitecturePremer.GateInExtensions}
GateIn extensions are special _.war_ files that are recognized by eXo Platform and contribute to custom configurations to the PortalContainer. To create your own portal, you will have to create a GateIn extension.

The extension mechanism makes possible to extend or even override portal resources in almost plug-and-play way. You simply add a _.war_ archive with your custom resources to the war folder and edit the configuration of the PortalContainerConfig service. Customizing a portal does not involve unpacking and repacking the original portal _.war_ archives. Instead, you need to create your own _.war_ archive with your own configurations, and modify resources. The content of your custom _.war_ archive overrides the resources in the original archives.

The most elegant way to reuse configuration for different coexisting portals is by way of extension mechanism. That is, you can inherit resources and configurations from existing web archives, then simply add extra resources and configurations to your extension, and override ones which need to be changed by including modified copies.

{note}
Starter is a web application which has been added to create and start all the portal containers once all the other web
applications have already been started. Generally, each web application of a portal container defines several things,
such as skins, JavaScripts, Google gadgets and configuration files, at its startup, so the loading order is important.
For example, at startup of the web application 1, skins or configuration files or JavaScripts are defined that could depend on another JavaScript from the web application 2. Thus, if the web application 2 is loaded after the web application 1, you will get errors in the merged JavaScript file.
{note}

If you ship servlets or servlet filters as part of your portal extension, and these servlets/servlet filters need to access specific resources of a portal during the process of the servlets or filters request, make sure that these servlets/filters are associated with the current portal container. The proper way to do that is making your servlet extend the _org.exoplatform.container.web.AbstractHttpServlet_ class. This will not only properly initialize the current _PortalContainer_ for you, but also set the current thread's context ClassLoader to servlets or servlet filters which looks for resources in associated web applications in the order specified by dependencies configuration.

As similar to filters, make  sure that your filter class extends _org.exoplatform.container.web.AbstractFilter_. Both _AbstractHttpServlet_ and _AbstractFilter_ have the method named _getContainer()_, which returns the current _PortalContainer_.


h2. Default Portal Container {anchor:id=DEV.eXoArchitecturePremer.defaultPortalContainer}

eXo Platform comes with a pre-configured PortalContainer named "portal". The configuration of this portal container ties the core and the extended services stack. The default Portal Container is started from _portal.war_ and naturally maps to the _/portal_ URL.

The GateIn extension mechanism lets you extend the portal context easily. With this feature, you only need to make your desired modifications on your extension, but NOT on the _portal.war_. As a result, your upgrades will become simple as your _extension.war_ is totally independent of the _portal.war_.

This extensibility is achieved via 2 advanced features of the _PortalContainer_:

* A unified ClassLoader: any classpath resource, such as property files, will be accessible as if it was inside the _portal.war_.

{note}
This is valid only for resources but not for Java classes.
{note}

* A unified ServletContext: any web resources contained in your _extension.war_ will be accessible from /portal/ uri.

For more details on how to make a simple extension for a "portal" container, see the [Register Extension|#DEV.eXoArchitecturePremer.RegisterExtension] section.

h2. Register Extension {anchor:id=DEV.eXoArchitecturePremer.RegisterExtension}

The webapps are loaded in the order defined in the list of dependencies of the _PortalContainerDefinition_. You then need to deploy the _starter.war_; otherwise, the webapps will be loaded in the default application server's order, such as the loading order of the Application Server.

If you need to customize your portal by adding a new extension and/or a new portal, you need to define the related _PortalContainerDefinitions_ and to deploy the starter. Otherwise, you do not need to define any _PortalContainerDefinition_.

First, you need to tell eXo Platform to load _WEB-INF/conf/configuration.xml_ of your extension, you need to declare it as a _PortalContainerConfigOwner_. Next, open the file _WEB-INF/web.xml_ of your extension and add a listener:

{code:xml}
<web-app>
  <display-name>my-portal</display-name>
    <listener>
      <listener-class>org.exoplatform.container.web.PortalContainerConfigOwner</listener-class>
    </listener>
  <!-- ... -->
</web-app>
{code}

You need to register your extension in the portal container. This is done by the *.xml* configuration file like this: 

{code:xml}
<external-component-plugins>
  <target-component>org.exoplatform.container.definition.PortalContainerConfig</target-component>
  <component-plugin>
    <name>Change PortalContainer Definitions</name>
    <set-method>registerChangePlugin</set-method>
    <type>org.exoplatform.container.definition.PortalContainerDefinitionChangePlugin</type>
    <init-params>
      <object-param>
        <name>change</name>
        <object type="org.exoplatform.container.definition.PortalContainerDefinitionChange$AddDependencies">
        <field name="dependencies">
          <collection type="java.util.ArrayList">
            <value>
              <string>my-portal</string>
            </value>
            <value>
              <string>my-portal-resources</string>
            </value>              
          </collection>
        </field>
        </object>
      </object-param> 
      <value-param>
        <name>apply.default</name>
        <value>true</value>
      </value-param>       
    </init-params>
  </component-plugin>
</external-component-plugins>
{code}


A _PortalContainerDefinitionChangePlugin_ plugin is defined to the _PortalContainerConfig_. The plugin declares a list of dependencies that are webapps. The _apply.default=true_ indicates that your extension is actually extending _portal.war_. You  need to package your extension into a *.war* file and put it to the tomcat webapps folder, then restart the server.

In your portal, if you want to add your own property file to support localization for your keys, you can do as follows:

- Put your property file into the _/WEB-INF/classes/locale/portal_ folder of your extension project.

- Add an external plugin declaration to the _.xml_ configuration file.	  

{code:xml}
<external-component-plugins>
  <!-- The full qualified name of the ResourceBundleService -->
  <target-component>org.exoplatform.services.resources.ResourceBundleService</target-component>
  <component-plugin>
    <!-- The name of the plugin -->
    <name>Sample ResourceBundle Plugin</name>
    <!-- The name of the method to call on the ResourceBundleService in order to register the ResourceBundles -->
    <set-method>addResourceBundle</set-method>
    <!-- The full qualified name of the BaseResourceBundlePlugin -->
    <type>org.exoplatform.services.resources.impl.BaseResourceBundlePlugin</type>
    <init-params>
      <!--values-param>
        <name>classpath.resources</name>
        <description>The resources that start with the following package name should be load from file system</description>
        <value>locale.portlet</value>
      </values-param-->
      <values-param>
        <name>init.resources</name>
        <description>Store the following resources into the db for the first launch </description>
        <value>locale.portal.sample</value>
      </values-param>
      <values-param>
        <name>portal.resource.names</name>
        <description>The properties files of the portal , those file will be merged
        into one ResoruceBundle properties </description>
        <value>locale.portal.sample</value>
      </values-param>
    </init-params>
  </component-plugin>
</external-component-plugins>
{code}

h1. Java Content Repository {anchor:id=DEV.eXoArchitecturePremer.JavaContentRepository}

All data of eXo Platform are stored in a Java Content Repository (JCR). JCR is the Java specification ([JSR-170|http://jcp.org/aboutJava/communityprocess/final/jsr170/index.html]) for a type of Object Database tailored to the storage, searching, and retrieval of hierarchical data. It is useful for the content management systems, which require storage of objects associated with metadata. The JCR also provides versioning, transactions, observations of changes in data, and import or export of data in XML. The data in JCR are stored hierarchically in a tree of nodes with associated properties.

Also, the JCR is primarily used as an internal storage engine. Accordingly, eXo Content lets you manipulate JCR data directly in several places. 


h2. Repositories and workspaces {anchor:id=DEV.eXoArchitecturePremer.Repositories&Workspaces}

A content repository consists of one or more workspaces. Each workspace contains a tree of items.

{docbook}
<para>
<citetitle>
<emphasis role="bold">
Access the repository's content from a service
</emphasis>
</citetitle>
</para>{docbook}

*1.* Get the session object.
{code:java}
import javax.jcr.Session;

import org.exoplatform.services.jcr.RepositoryService;
import org.exoplatform.services.jcr.core.ManageableRepository;
import org.exoplatform.services.jcr.ext.common.SessionProvider;
import org.exoplatform.services.wcm.utils.WCMCoreUtils;

// For example
RepositoryService repositoryService = WCMCoreUtils.getService(RepositoryService.class);
ManageableRepository manageableRepository = repositoryService.getRepository(repository);
SessionProvider sessionProvider = WCMCoreUtils.getSessionProvider();
Session session = sessionProvider.getSession(workspace, manageableRepository);
{code}

*i.* Obtain the _javax.jcr.Repository_ object via one of the following ways:

*The first way*

Call the _getRepository()_ method of _RepositoryService_.


{code:java}
RepositoryService repositoryService = (RepositoryService) container.getComponentInstanceOfType(RepositoryService.class);
Repository repository = repositoryService.getRepository("repositoryName");
{code}

*The second way*

Call the _getCurrentRepository()_ method, especially when you plan to use a single repository which covers more than 90% of usecases.

{code:java}
// set current repository at initial time
RepositoryService repositoryService = (RepositoryService) container.getComponentInstanceOfType(RepositoryService.class);
repositoryService.setCurrentRepositoryName("repositoryName");
....
// retrieve and use this  repository
Repository repository = repositoryService.getCurrentRepository();
{code}

*The third way*

Using JNDI as specified in [JSR-170|http://jcp.org/aboutJava/communityprocess/final/jsr170/index.html].

{code:java}
Context ctx = new InitialContext();
Repository repository =(Repository) ctx.lookup("repositoryName");
{code}

*ii.* Log in the server to get a Session object by either of two ways:

*The first way*

Create a Credential object, for example:

{code:java}
Credentials credentials = new SimpleCredentials("exo", "exo".toCharArray());

Session jcrSession = repository.login(credentials, "production");
{code}

*The second way*

Log in the server without using a Credential object.

{code:java}
Session jcrSession = repository.login("production");
{code}

This way is only applied when you run an implementation of eXo Platform. The eXo Platform implementation will directly
leverage the organization and security services that rely on LDAP or DB storage and JAAS login modules.
Single-Sign-On products can now also be used as eXo Platform v.2 which supports them.

{note}
There are some JCR Session common considerations as follows:

Because _javax.jcr.Session_ is not a safe object of thread, it is recommended that you should not share it between threads.

Do not use the System session from the user-related code because a system session has unlimited rights. Call _ManageableRepository.getSystemSession()_ from the process-related code only.

Call _Session.logout()_ explicitly to release resources assigned to the session.

When designing your application, you should take care of the Session policy inside your application. Two strategies are possible: Stateless (Session per business request) and Stateful (Session per User) or some mixings.
{note}

*2.* Retrieve your node content of the session object.

{code:java}
String path = "/"; // put your node path here

Node node = (Node) session.getItem(path);
{code}

h2. Tree structure: working with nodes and properties {anchor:id=DEV.eXoArchitecturePremer.WorkingWithNodes&Properties}

Every node can only have one primary node type. The primary node type defines names, types and other characteristics of the properties, and the number of its allowed child nodes.
Every node has a special property called _jcr\:primaryType_ that records the name of its primary node type. A node may also have one or more mixin types. These are node type definitions that can mandate extra characteristics (for example, more child nodes, properties and their respective names and types).

Data are stored in properties, which may hold simple values, such as numbers, strings or binary data of arbitrary length.

The JCR API provides methods to define node types and node properties, create or delete nodes, and add or delete properties from an existing node.

You can refer to the "6.2.3 Node Read Methods" in the JCR Specification document.
