Tag: AEM6

OOTB checkbox is not available in AEM 6.3 metadata schema editor. But, it can be enabled and used with steps as described below.

Step 1: Overlay builditems.jsp to Enable checkbox

Create an /apps overlay for “/libs/dam/gui/coral/components/admin/schemaforms/formbuilder/builditems.jsp“

In “/apps/dam/gui/coral/components/admin/schemaforms/formbuilder/builditems.jsp“, uncomment the following snippet. It would be available between line 90-98

At this point, browse to a metadata schema editor:

Click on navigation rail. Browse to Tools > Assets > Metadata Schemas

Click on default > Select edit

Notice that checkbox is available in the menu.

Though you can currently add checkbox for a metadata schema, you will not be able to persist the checkbox state properly.

Step 2: Persisting checkbox state

Create an /apps overlay for “/libs/dam/gui/coral/components/admin/metadataeditor/clientlibs/metadataeditor/js/form.js”

In “/apps/dam/gui/coral/components/admin/metadataeditor/clientlibs/metadataeditor/js/form.js”, add ONLY lines 27-52 from following snippet. Please note the placement relative to an existing function “allCheckbox.each(function (index, checkbox))”

While the Apache Felix Maven SCR Plugin is a great tool (see below), for developing OSGi components using Declarative Services you should use the official annotations from the OSGi R6 specification. The development of the Apache Felix SCR Plugin is in maintenance mode.

The examples and dependencies have been verified on AEM 6.3 Instance

Maven dependency changes:

In order to use the new OSGi annotations, we need to add following dependencies to pom.xml.

For a project upgrading from Felix to DS annotations, you can remove following:

All Felix dependencies. Example:

org.apache.felix.scr.annotations

biz.aQute.bnd

Plugins

maven-scr-plugin: is required to resolve felix annotations at build time

Code changes:

You can choose to update java files at once, or one-by-one.

Incase you wish to modify all files together, then remove felix dependencies and plugins. The IDE would now recognize all the files that need modifcation.

However, if you wish to change files one-by-one, then you can keep both DS and Felix dependencies in pom.xml. A bundle with both types of annotations would still be good. Once all the code changes are done, you should remove all felix dependencies.

How to identify the changes:

You can easily identify the files, by looking for package imports of “org.apache.felix.scr.annotations.*”.

We would be using the following packages instead:

org.osgi.service.component.annotations.*

org.osgi.service.metatype.annotations.*

For more details on code changes involved, please visit the specific links:

Multiple Service Implementation can be used to define multiple implementations of a Service, and then execute all/specific implementation depending on the use-case.

A close example would be Replication Agents. Here a specific replication implementation (Static Agent, Default Agent, Custom Transport Handler/Builders etc) is called, depending on the configuration.

Lets construct a multiple service implementation via an Example.

Scenario:

Consider an online course website. A lecturer can publish his content by submitting a course bundle comprising of html pages, videos and assessment questions.

While the bundle is processed, each content type is to be dealt with specific import-service implementation:

Page import

Video import

Assessment import

Lets get started with the implementation !!!

Create multiple service implementation

The implementation can be divided into 3 simple steps:

Create an interface which each of Service implementation would implement.

Implement concrete service implementations

A handler which would hold list of service implementation & execute relevent implementation.

Step 1: Interface which each service implementation would implement

The interface would comprise of abstract methods which:

would execute business logic for each service.

allow identification of best service to process current use-case.

Sample interface for the course import scenario:

package blog.techrevel.service;
public interface CourseImport {
//Import pages, videos and assessment
public abstract void importContent();
//Identify the service which would be able to process current file
public abstract boolean canProcess(String fileName);
}

Step 2: Implement concrete service implementations

Here we would be create multiple content import implementation to deal specifically with each content type. Example:

If dynamic the service will be made available to the component as it comes and goes.

If static the component will be deactivated and re-activated if the service comes and/or goes away

unbind=”name of the method to be called when the service is to be unbound from the component”

To declare no unbind method, the value "-" must be used.

If not specified, the name of the unbind method is derived from the name of the annotated bind method. If the annotated method name begins with bind, set or add, that is replaced withunbind, unset or remove, respectively, to derive the unbind method name. Otherwise, un is prefixed to the annotated method name to derive the unbind method name. The unbind method is only set if the component type contains a method with the derived name.

OSGi provides many modular features which enhances a developer’s implementation experience. Current blog focuses on one such feature: Configuration Factories via new OSGi Annotations

The concept is similar to logging configuration in AEM, where we define multiple configurations for different loggers, but the service implementation stays the same. Thus, multiple configuration, single implementation.

Create and access a configuration factory

It takes just two steps to create and use a Configuration factory.

Step 1: Create Configuration factory

This is achieved by adding ‘factory=true’ attribute to the Component annotation.

If dynamic the service will be made available to the component as it comes and goes.

If static the component will be deactivated and re-activated if the service comes and/or goes away

unbind=”name of the method to be called when the service is to be unbound from the component”

To declare no unbind method, the value "-" must be used.

If not specified, the name of the unbind method is derived from the name of the annotated bind method. If the annotated method name begins with bind, set or add, that is replaced withunbind, unset or remove, respectively, to derive the unbind method name. Otherwise, un is prefixed to the annotated method name to derive the unbind method name. The unbind method is only set if the component type contains a method with the derived name.

Here we would be discussing, on how to filter the references and get ONLY pre-defined specific implementation

Scenario:

Consider an online course website. A lecturer can publish his content by submitting a course bundle comprising of html pages, videos and assessment questions.

The lecturer had his/her course live for an year & is appreciated by many curious students. The lecturer now wishes to update the assessment questionnaire, to challenge students to dig deeper.

He/She now submit the latest questionnaire to the onlint course portal for updates.

At this point, the course website needs to assure, that only the “Assessment Import” service implementation is called amogst all available Import implementation (Page, Videos and Assessment)

Implementation details:

Specific service references can be fetched by utilizing the “target” attribute of @Reference annotation. It would comprise of 2 simple steps

Step 1: Add property to identify each implementation

You can add any custom property to uniquely identify the service. For example, in the below sample code, I have added “type” property to uniquely identify my each implementation of CourseImport Service

Multiple Service Implementation can be used to define multiple implementations of a Service, and then execute all/specific implementation depending on the use-case.

A close example would be Replication Agents. Here a specific replication implementation (Static Agent, Default Agent, Custom Transport Handler/Builders etc) is called, depending on the configuration.

Lets construct a multiple service implementation via an Example.

Scenario:

Consider an online course website. A lecturer can publish his content by submitting a course bundle comprising of html pages, videos and assessment questions.

While the bundle is processed, each content type is to be dealt with specific import-service implementation:

Page import

Video import

Assessment import

Lets get started with the implementation !!!

Create multiple service implementation

The implementation can be divided into 3 simple steps:

Create an interface which each of Service implementation would implement.

Implement concrete service implementations

A handler which would hold list of service implementation & execute relevent implementation.

Step 1: Interface which each service implementation would implement

The interface would comprise of abstract methods which:

would execute business logic for each service.

allow identification of best service to process current use-case.

Sample interface for the course import scenario:

package blog.techrevel.service;
public interface CourseImport {
//Import pages, videos and assessment
public abstract void importContent();
//Identify the service which would be able to process current file
public abstract boolean canProcess(String fileName);
}

Step 2: Implement concrete service implementations

Here we would be create multiple content import implementation to deal specifically with each content type. Example:

The concept is similar to logging configuration in AEM, where we define multiple configurations for different loggers, but the service implementation stays the same. Thus, multiple configuration, single implementation.

Create and access a configuration factory

It takes just two steps to create and use a Configuration factory.

Step 1: Create Configuration factory

This is achieved by adding ‘configurationFactory=true’ attribute to the Component annotation.