Workplace services extensions

Adding extension classes

It is possible to add extension classes to extend content creation builded by Workplace.

Extension classes dependencies

Extension classes must extend com.moovapps.workplace.sdk.extension.base.BaseApplicationBuilderExtension. Therefore, the project containing these classes must have as dependency moovapps-workplace-sdk.

Extension classes declaration

In the Workplace Services configuration, a Development section is visible to sysadmin user and members of the Workplace developers group. In the Extension Classes field it is possible to declare the reference to one or more extension classes. When calling extension class methods, they will be executed in the order in which the classes were declared. The text entered in parameters section can be retrieved in the extension classes in order to be used for preocessing. Example image Example image

Operating

When a service is created, modified, deleted or when its reference is changed, an IApplicationBuilder object modifies the content of the Workplace site related to that service. (Note: for services such as link and link to a moovapps application, no content is modified). Through a proxy on the IApplicationBuilder, the extension classes are called during these content modifications. In these extension classes the relevant service is represented by an IApplication object.

Design of extension classes

Methods to be implemented

The Workplace site has content related to existing services. As changes are made to the services, this content is modified. Extension class methods are triggered before (onBefore), after (onAfter) and in case of exception (on___Exception) during modifications.

onBeforeUpdateContent, onAfterUpdateContent, onUpdateContentException

When a service is created or modified, the content of the Workplace site linked to that service is modified. onBeforeUpdateContent allows processing before this modification. onAfterUpdateContent allows processing after this modification. onUpdateContentException allows processing if an exception occurs during this modification.

onBeforeDeleteContent, onAfterDeleteContent, onDeleteContentException

When a service is removed, the content of the Workplace site linked to that service is deleted. onBeforeDeleteContent allows processing before this deletion. onAfterDeleteContent allows processing after this deletion. onDeleteContentException allows you to process if an exception occurs during this deletion.

onBeforeRenameAssociatedComponents, onAfterRenameAssociatedComponents, onRenameAssociatedComponentsException

When changing the reference of a service, the section of the Workplace site in which the content of the service is located is renamed. onBeforeRenameAssociatedComponents allows processing before this renaming. onAfterRenameAssociatedComponents allows processing after this renaming. onRenameAssociatedComponentsException allows you to perform processing if an exception occurs during this renaming.

Utility methods

In order to make it easier to access elements of the Workplace site, the BaseApplicationBuilderExtension class provides utility methods.

getPageContainer

This method allows you to find the page of the Workplace site corresponding to a service. If no content exists for this service, this method will return null.

getTopic

This method allows you to find the topic of the Workplace site corresponding to a service, the page of the service is contained in this topic. If no content exists for this service, this method will return null.

getCustomTopic

This method allows you to find the Custom topic of the Workplace site.

Exemples

You can download samples here

Copy of a thematic page

package com.moovapps.process.extensions;

import com.axemble.vdoc.sdk.Modules;
import com.axemble.vdoc.sdk.exceptions.SiteModuleException;
import com.axemble.vdoc.sdk.interfaces.IContext;
import com.axemble.vdoc.sdk.interfaces.IPageContainer;
import com.axemble.vdoc.sdk.interfaces.ISite;
import com.axemble.vdoc.sdk.interfaces.ITopic;
import com.axemble.vdoc.sdk.modules.ISiteModule;
import com.moovapps.workplace.sdk.beans.IApplication;
import com.moovapps.workplace.sdk.beans.types.ApplicationType;
import com.moovapps.workplace.sdk.extension.base.BaseApplicationBuilderExtension;
import com.moovapps.workplace.sdk.modules.IWorkplaceModule;
import com.moovapps.workplace.sdk.modules.factory.WorkplaceModuleFactory;
import org.apache.commons.lang3.Validate;

public class ThematicBuilderExtension extends BaseApplicationBuilderExtension {

    private static final com.axemble.vdoc.sdk.utils.Logger LOG = com.axemble.vdoc.sdk.utils.Logger.getLogger(ThematicBuilderExtension.class);

    @Override
    public void onAfterUpdateContent(IApplication application)
    {
        //Getting a site module
        ISiteModule siteModule = Modules.getSiteModule();
        try {
            //We are going to use the parameters
            Validate.notNull(application.getParameters());

            //We allow treatment only if the application is a link-type application
            Validate.isTrue(ApplicationType.LINK.getKey().equals(application.getType().getKey()));

            //Treatment will be done in a transaction
            siteModule.beginTransaction();

            //We do the treatment as sysadmin
            IContext context = siteModule.getSysadminContext();

            //Retreieving workplace site
            IWorkplaceModule workplaceModule = WorkplaceModuleFactory.getWorkplaceModule();
            ISite site = siteModule.getSiteByName(context, workplaceModule.getWorkplaceSiteName());

            //We check if the content we want to make already exists and delete it
            ITopic topic = siteModule.getTopic(context,getCustomTopic(),application.getParameters());
            if(topic != null) {
                IPageContainer container = siteModule.getPageContainer(context,topic,"index");
                if(container != null){
                    siteModule.delete(context,container);
                }
                siteModule.delete(context,topic);
            }

            //We create some content (by copying a custom page)
            topic = siteModule.createTopic(context, getCustomTopic(), application.getParameters(), application.getParameters());
            IPageContainer templatePage = siteModule.getPageContainer(context, site, "custom/thematic/index");
            siteModule.copyPageContainerInTopic(context, templatePage, topic);

            //We approve the new content
            IPageContainer container = siteModule.getPageContainer(context,topic,"index");
            siteModule.approve(context, container);

            //We update the application to have its link pointed at
            application.setLink(container.getProtocolURI());

            siteModule.commitTransaction();

        } catch (SiteModuleException e) {
            LOG.error(e);
        } finally {
            if (siteModule.isTransactionActive()) {
                siteModule.rollbackTransaction();
            }
            Modules.releaseModule(siteModule);
        }
    }
}

Adding a Data Store View

package com.moovapps.process.extensions;

import com.axemble.easysite.dao.domain.impl.BlockImpl;
import com.axemble.sdk.blocks.sys.layouts.SimpleBlock;
import com.axemble.sdk.components.sys.navigation.HyperlinkComponent;
import com.axemble.sdk.components.sys.texts.HeadingComponent;
import com.axemble.sdk.components.sys.views.DataComponent;
import com.axemble.vdoc.sdk.Modules;
import com.axemble.vdoc.sdk.exceptions.SiteModuleException;
import com.axemble.vdoc.sdk.interfaces.IBlock;
import com.axemble.vdoc.sdk.interfaces.IContent;
import com.axemble.vdoc.sdk.interfaces.IContext;
import com.axemble.vdoc.sdk.interfaces.IPageContainer;
import com.axemble.vdoc.sdk.modules.ISiteModule;
import com.moovapps.workplace.sdk.beans.IApplication;
import com.moovapps.workplace.sdk.beans.types.ApplicationType;
import com.moovapps.workplace.sdk.extension.base.BaseApplicationBuilderExtension;
import org.apache.commons.lang3.Validate;

import java.util.ArrayList;
import java.util.List;

public class AddressViewBuilderExtension extends BaseApplicationBuilderExtension {

    private static final com.axemble.vdoc.sdk.utils.Logger LOG = com.axemble.vdoc.sdk.utils.Logger.getLogger(AddressViewBuilderExtension.class);

    @Override
    public void onAfterUpdateContent(IApplication application)
    {
        //Getting a site module
        ISiteModule siteModule = Modules.getSiteModule();
        try {

            //We allow treatment only if the application is a process-type application
            Validate.isTrue(ApplicationType.PROCESS.getKey().equals(application.getType().getKey()));

            //Treatment will be done in a transaction
            siteModule.beginTransaction();

            //Treatment will be done as sysadmin
            IContext context = siteModule.getSysadminContext();

            //Getting the draft content for the page
            IPageContainer applicationPage = getPageContainer(application);
            IContent draftContent = applicationPage.getContent(IContent.IStatus.DRAFT);

            //Add the storage view to the page
            addStorageView(siteModule, draftContent);
            draftContent.save(context);

            //Approve the page
            siteModule.approve(context, applicationPage);

            siteModule.commitTransaction();

        } catch (SiteModuleException e) {
            LOG.error(e);
        } finally {
            if (siteModule.isTransactionActive()) {
                siteModule.rollbackTransaction();
            }
            Modules.releaseModule(siteModule);
        }
    }

    private void addStorageView(ISiteModule siteModule, IContent draftContent) throws SiteModuleException {
        //Getting the custom part of the menu and clearing it
        IBlock menuBlock = draftContent.getBlock().findBlockBySystemName("menu-custom", true);
        ((BlockImpl) menuBlock.getNativeObject()).getAdditionalNodeList().clear();

        //Creating a block and a link inside it
        SimpleBlock simpleBlock = siteModule.getBlocksFactory().newSimpleBlock();
        simpleBlock.setInnerName("MENU-STORAGE_VIEW");
        simpleBlock.setInnerLabel("STORAGE_VIEW");
        HyperlinkComponent hyperlink = siteModule.getComponentsFactory().newHyperlinkComponent();
        hyperlink.setLabel("Mes adresses");
        hyperlink.setTarget("_self");
        //the block parameter in the menu link will be used by the page to display the matching content <-- Important
        hyperlink.setValue("href","?block=STORAGE_VIEW");
        simpleBlock.addComponent(hyperlink);
        menuBlock.addBlock(simpleBlock);

        //Getting the custom part of the content and clearing it
        IBlock contentBlock = draftContent.getBlock().findBlockBySystemName("content-custom", true);
        ((BlockImpl) contentBlock.getNativeObject()).getAdditionalNodeList().clear();

        //Creating the content
        //We need a block with system name matching the parameter of the link from the menu <-- Important
        SimpleBlock contentSimpleBlock = siteModule.getBlocksFactory().newSimpleBlock();
        contentSimpleBlock.setInnerName("CONTENT-STORAGE_VIEW");
        contentSimpleBlock.setInnerLabel("STORAGE_VIEW");
        //We put a header on top of the view
        HeadingComponent headingComponent = siteModule.getComponentsFactory().newHeadingComponent();
        headingComponent.setLevel("1");
        headingComponent.setContent("Mes adresses");
        contentSimpleBlock.addComponent(headingComponent);
        //We add a component to show a view and parameterize it
        DataComponent dataComponent = siteModule.getComponentsFactory().newDataComponent();
        dataComponent.setDefaultDisplayMode("list");
        dataComponent.setNbElementsPerPage("25");
        dataComponent.setUsePlugin(false);
        List<String> viewList = new ArrayList();
        viewList.add("uril://vdoc/resourceDefinitionView/DefaultOrganization/MoovappsWorkplace/Companies:4/Address/DEFAULT");
        dataComponent.setViewList(viewList);
        contentSimpleBlock.addComponent(dataComponent);

        //We add our content to the custom content block
        contentBlock.addBlock(contentSimpleBlock);
    }
}