AModuleComponent executes code and is tied to a specificModule. It is packed with the rest of the module files in an AMP or JAR.
Architecture Information:Platform Architecture
An Content Services module, such as an AMP or a JAR, can have tightly coupled components (that is, Java classes) that are part of its implementation. When a module is loaded it will also execute the code for each one of its registered components. One component can depend on another component, so it is possible to set up the required execution order. A component can also be associated with a Content Services version range for which it is valid, which means that it will only be invoked if current Content Services version is in this version range. By default each one of the components will be executed only once when the module is deployed for the first time. To implement a module component you first need aRepository AMP project or a repository JAR project. Then start by implementing the component class as in the following example:
public class DemoComponent extends AbstractModuleComponent { Log log = LogFactory.getLog(DemoComponent.class); @Override protected void executeInternal() throws Throwable { System.out.println("DemoComponent has been executed"); log.debug("Test debug logging. Number of nodes in Company Home = " + childNodesCount(getCompanyHome())); log.info("This is only for information purposed. Better remove me from the log in Production"); } public int childNodesCount(NodeRef nodeRef) { return serviceRegistry.getNodeService().countChildAssocs(nodeRef, true); } public NodeRef getCompanyHome() { return serviceRegistry.getNodeLocatorService().getNode("companyhome", null, null); }}All components should extend theorg.alfresco.repo.module.AbstractModuleComponent class, it provides a lot of general plumbing so you don’t have to do it. For example, it provides defaults for properties such asexecuteOnceOnly and it provides aserviceRegistry so you can get to the public API. The main method that needs to be implemented is calledexecuteInternal and it should contain the work that needs to be done when this component is executed by the module. There can be other methods in the component that provides services useful to other parts of the module implementation. When the component implementation is done it needs to be registered with the module, this is done with a Spring bean as follows:
<bean parent="module.baseComponent" > <property name="moduleId" value="${project.artifactId}" /> <!-- See module.properties --> <property name="name" value="exampleComponent" /> <property name="description" value="A demonstration component" /> <property name="sinceVersion" value="2.0" /> <property name="appliesFromVersion" value="2.0" /></bean>The component Spring bean should extend (have asparent) themodule.baseComponent bean, which will have theServiceRegistry property defined and theinit-method defined so it will be automatically registered with the module. The module that the component will be registered with is determined by themoduleId property, which should be set to the module id for the repository AMP or repository JAR. ThesinceVersion andappliesFromVersion properties can be used to indicate for what Content Services versions this component should be activated.
If you want a component to be executed after another component use thedependsOn property as follows:
<bean parent="module.baseComponent"> <property name="moduleId" value="${project.artifactId}" /> <!-- See module.properties --> <property name="name" value="anotherExampleComponent" /> <property name="description" value="Another demonstration component" /> <property name="sinceVersion" value="2.0" /> <property name="appliesFromVersion" value="2.0" /> <property name="dependsOn"> <ref bean="org.alfresco.tutorial.exampleComponent" /> </property></bean>To execute the component at every server start use the following property:
<property name="executeOnceOnly" value="false" />There is a special component implementation available out-of-the-box for importing content into the repository. It is calledImporterModuleComponent and you can use it by defining the a Spring bean like this:
<bean parent="module.baseComponent"> <property name="moduleId" value="my-module-id" /> <property name="name" value="MyBootstrapModule" /> <property name="description" value="My Modules initial data requirements" /> <property name="sinceVersion" value="1.0" /> <property name="appliesFromVersion" value="1.0" /> <property name="appliesToVersion" value="1.4" /> <property name="importer" ref="spacesBootstrap" /> <property name="bootstrapViews"> <list> <props> <prop key="path">/${spaces.company_home.childname}</prop> <prop key="location">alfresco/module/myModule-123/myACP.acp</prop> </props> </list> </property></bean>Note here the use also of theappliesToVersion property. For more information about bootstrapping content see thisextension point.
tomcat/shared/classes/alfresco/extension/some-context.xml - Define your component Spring beans here (Untouched by re-deployments and upgrades)aio/platform-jar/src/main/java/{custom package path} - implementation of module componentsaio/platform-jar/src/main/resources/alfresco/module/platform-jar/context/service-context.xml - Component Spring Bean definitions