Extending Commerce Manager
Extending Commerce Manager
Commerce Manager's existing UI can be extended to display information and accommodate extended data objects from Commerce Engine. Commerce Manager UI extensions utilize Eclipse Extension Points.
Commerce Manager Pattern Catalog
The Commerce Manager Pattern Catalog offers working examples of all Commerce Manager extension types. The catalog can be loaded into /extensions as a standalone plugin.
When developing a new extension point, it is strongly recommended to use one of the working examples in the catalog as a starting point and modify it to suit your needs.
Creating an Extended Plugin
All extensions are created as a plugin in the extensions/cm/ext-cm-modules/ext-plugins folder, and extend the plugin in which the UI element you want to extend exists. For example, if you want to extend a table in the Price List Manager activity, your plugin should extend com.elasticpath.cmclient.pricelistmanager.
Your plugin should contain the following:
- A META-INF/MANIFEST.MF file.
- A plugin.xml in the root of the plugin's folder.
- A pom.xml file in the root of the plugin's folder.
- A build.properties file in the root of the plugin's folder.
- Your extended Java classes, typically in a /src/main/java/com/elasticpath/extensions folder.
These property files are discussed in the Registering Your Plugin section in detail.
Understanding Extension Points
Commerce Manager plugins provide three types of Eclipse extension points: a generic Extender, a StatePolicyExtender and a PromotionsExtender. Each out of the box plugin defines which extension points it provides in its plugin.xml file.
Each extender refers to an .exsd schema located in com.elasticpath.cmclient.core, which defines which fields are needed for an extension point contribution to be recognized as valid.
Extender
The generic Extender is provided by all out of the box plugins as follows:
<extension-point id="Extender" name="Extender" schema="../com.elasticpath.cmclient.core/schema/extender.exsd"/commerce-legacy/>
State Policy Extender
The State Policy Extension Point is designed to handle specific information around extending and creating new state policy determiners. State Policy provides its own extension point and schema in all plugins' plugin.xml as follows:
<extension-point id="StatePolicyExtender" name="StatePolicyExtender" schema="../com.elasticpath.cmclient.core/schema/statePolicyExtender.exsd"/commerce-legacy/>
For more information, see State Policies.
Promotions Extender
The Promotions Extension Point is designed to handle specific information around extending and creating promotion rules. Promotions can only be extended from the com.elasticpath.cmclient.store plugin and also has its own extension point, defined within store's plugin.xml:
<extension-point id="PromotionExtender" name="PromotionExtender" schema="../com.elasticpath.cmclient.core/schema/promotionExtender.exsd"/commerce-legacy/>
Defining an Extension Point in an Extended Plugin
In your plugin's plugin.xml, you will need to define an extension point using the .exsd schemas and Extenders above. Regardless of the type of extension point, when referring to an extender, the nomenclature is always a particular plugin's Extender class.
The basic requirements for defining an extension point in your plugin.xml file are as follows:
- An <extension> element, which has a point
attribute.
- point should refer to the Extender class of the plugin you wish to extend.
- A child element of <extension> which defines the type of
extension you are trying to create. It can be one of the following:
Element Description Attributes <Page> Adds a new page to an Editor. editorName – The Editor to add the page to.
className – Where the code for the extended or additional page is found. This must refer to a class that implements com.elasticpath.cmclient.core.helpers.extenders.EpPageCreator.
<TableColumn> Adds a column to a table. table – The Table to add a column to.
className – Where the code for the extended table is found. This must refer to a class that implements com.elasticpath.cmclient.core.helpers.extenders.EpTableColumnCreator.
<Section> Adds a section to a page. pageId – The Page to add the section to.
className – Where the code for the extended page section is found. This must refer to a class that implements com.elasticpath.cmclient.core.helpers.extenders.EpSectionCreator.<Dialog> Adds a new dialog. dialogName – The class name of the of the Dialog to attach to. This dialog must extend AbstractEpDialog.
className – Where the code for the additional dialog is found. This must refer to a class that implements com.elasticpath.cmclient.core.helpers.extenders.DialogExtension.
<Determiners> Adds a new State Policy Determiner. For more on creating State Policy Determiners, see State Policies. policyToApplyTo – The class name of the policy to extend.
containerName – The policy container name.
className – Where the code for the additional or extended State Policy Determiner is found. This must refer to a class that implements com.elasticpath.cmclient.policy.StateDeterminer.
Examples of all extension points can be found in the Commerce Manager Pattern Catalog.
Example: A TableColumn Extension Point
The following example defines an extension point for a new table column in the catalog plugin's BrowseProductListView table:
<extension point="com.elasticpath.cmclient.catalog.Extender"> <TableColumn table="BrowseProductListView" className="com.elasticpath.extensions.table.ExampleTableColumn"/commerce-legacy/> </extension>
Example: A Page Extension Point
EpPageCreator and EpSectionCreator are all implemented as an inner class to your extension class, typically named Creator. The extension declaration for these therefore refers to the Creator class directly as follows:
<extension point="com.elasticpath.cmclient.pricelistmanager.Extender"> <Page editorName="PriceListEditor" className="com.elasticpath.extensions.page.ExamplePage$Creator"/commerce-legacy/> </extension>
Promotions Extension Points
The Promotions extension point follows a slightly different pattern. Within an <extension>, you must define all of the following:
Element | Description | Attributes |
---|---|---|
<Messaging> | Name of the extended messaging class. | className – where the code for the extended Messaging class can be found. This must refer to a class that implements com.elasticpath.cmclient.core.helpers.extenders.MessageReader. |
<Widget> | Name of the Widget extension class. | className – where the code for the extended Widget class can be found. This must refer to a class that implements com.elasticpath.cmclient.core.helpers.extenders.PromotionWidgetCreator. |
Example: A Promotions Extension Point
An example of a definition for a Promotions extension point in an extended store plugin's plugin.xml file is as follows:
<extension point="com.elasticpath.cmclient.store.Extender"> <Messaging className="com.elasticpath.extensions.promotions.ExampleMessaging"></Messaging> <Widget className="com.elasticpath.extensions.promotions.ExampleWidget"></Widget> </extension>
Condition Builder Extension Points
Element | Description | Attributes |
---|---|---|
ConditionRowCompositeCreatorFactory | Name of the factory class extension plugin used to create ConditionRowComposites | className – where the code for the extended ConditionRowCompositeCreatorFactory class is located. This class name must refer to a class that implements com.elasticpath.cmclient.conditionbuilder.extenders.ConditionRowCompositeCreatorFactory.. |
ConditionModelAdapterFactory | Name of the factory class extension plugin used to create ConditionModelAdapters | className – where the code for the extended ConditionModelAdapterFactory class is located. This class name must refer to a class that implements com.elasticpath.cmclient.conditionbuilder.extenders.ConditionModelAdapterFactory. |
Example: A Condition Builder Extension Point
The following is an example of a definition for a condition builder extension point in an extended store plugin's plugin.xml file:
<extension point="com.elasticpath.cmclient.conditionbuilder.ConditionBuilderExtender"> <ConditionRowCompositeCreatorFactory className="com.elasticpath.cm.conditionbuilder.ExtConditionRowCompositeCreatorFactory"> </ConditionRowCompositeCreatorFactory> <ConditionModelAdapterFactory className="com.elasticpath.cm.conditionbuilder.ExtConditionModelAdapterFactory"> </ConditionModelAdapterFactory> </extension> <extension point="com.elasticpath.cmclient.core.ModelExtender"> <Condition className="com.elasticpath.cm.conditionbuilder.ExtCondition"> </Condition> </extension>
Implementing an Extended Plugin
Depending on what you are extending, your class will either implement an interface or extend an abstract class from the com.elasticpath.cmclient.core.helpers.extenders package, or extend an abstract class from com.elasticpath.cmclient.core.editors.
For full examples, see the Commerce Manager Pattern Catalog.
Extending BaseAmount
- To extend BaseAmount. extend the following classes at
extensons/core/:
- ExtBaseAmountDTO: Extends the BaseAmountDTO.
- ExtBaseAmountDTOCreator: Overrides the default DTO creator to use the ExtBaseAmountDTO.
Note: Ensure that the plugin.xml and MANIFEST.MF files are updated as required. For more information see, META-INF/MANIFEST.MF and pom.xml sections. - To display the new fields from the ExtendedBaseAmountDTO, extend the
dialogs and tables.
For more information about extending tables and dialogs, see Extending Tables and Extending Dialogs.
Example Procedure
- To extend the base amount, extend the ExtBaseAmountDTOCreator class:
package com.extensions.baseamount.impl; import com.elasticpath.cmclient.core.helpers.extenders.EpModelCreator; import com.elasticpath.common.dto.pricing.BaseAmountDTO; import com.elasticpath.extensions.domain.impl.ExtBaseAmountDTO; /** * Example Base Amount DTO model creator. */ public class ExtBaseAmountDTOCreator implements EpModelCreator<BaseAmountDTO> { @Override public BaseAmountDTO createModel() { return new ExtBaseAmountDTO(); } @Override public BaseAmountDTO createModel(final BaseAmountDTO other) { return new ExtBaseAmountDTO(other); } }
- To implement the changes, update the plugin.xml file with the
following:
<extension point="com.elasticpath.cmclient.core.ModelExtender"> <BaseAmountDTO className="com.extensions.baseamount.impl.ExtBaseAmountDTOCreator"/commerce-legacy/> </extension>
- To display the changes in a dialog, extend the BaseAmountDialog
class as in the following
example:
package com.extensions.baseamount.impl; import org.eclipse.swt.widgets.Text; import com.elasticpath.cmclient.core.helpers.extenders.DialogExtension; import com.elasticpath.cmclient.core.ui.dialog.AbstractEpDialog; import com.elasticpath.cmclient.core.ui.framework.EpControlFactory; import com.elasticpath.cmclient.core.ui.framework.IEpLayoutComposite; import com.elasticpath.cmclient.core.ui.framework.IEpLayoutData; import com.elasticpath.extensions.domain.impl.ExtBaseAmountDTO; /** * Example Base Amount Dialog Extension. */ public class BaseAmountDialogExtension implements DialogExtension { private Text extendedText; @Override public void bindControls(final AbstractEpDialog dialog) { //not used. } @Override public void populateControls(final AbstractEpDialog dialog) { ExtBaseAmountDTO model = (ExtBaseAmountDTO) dialog.getModel(); this.extendedText.setText(model.getSomething()); } @Override public void createEpDialogContent(final IEpLayoutComposite composite, final AbstractEpDialog dialog) { final IEpLayoutData labelData = composite.createLayoutData(IEpLayoutData.END, IEpLayoutData.FILL); final IEpLayoutData fieldData = composite.createLayoutData(IEpLayoutData.FILL, IEpLayoutData.BEGINNING, true, false); composite.addLabelBoldRequired("Extended Base Amount Field:", EpControlFactory.EpState.EDITABLE, labelData); extendedText = composite.addTextField(EpControlFactory.EpState.EDITABLE, fieldData); } }
- Update the plugin.xml file with the following for the
BaseAmountDialog class extension:
<extension point="com.elasticpath.cmclient.pricelistmanager.Extender"> <Dialog dialogName="BaseAmountDialog" className="com.extensions.baseamount.impl.BaseAmountDialogExtension"/commerce-legacy/> </extension>
- Override the
assembler:
package com.elasticpath.extensions.domain.impl; import org.apache.log4j.Logger; import com.elasticpath.common.dto.assembler.pricing.BaseAmountDtoAssembler; import com.elasticpath.common.dto.pricing.BaseAmountDTO; /** * Extension BaseAmount DTO Assembler. */ public class ExtBaseAmountDtoAssembler extends BaseAmountDtoAssembler { private static final Logger LOG = Logger.getLogger(ExtBaseAmountDtoAssembler.class); @Override public BaseAmountDTO getDtoInstance() { LOG.warn("using extension assembler"); return new ExtBaseAmountDTO(); } }
Ensure that the spring bean for the assembler is overridden as follows:<bean id="baseAmountDtoAssembler" class="com.elasticpath.extensions.domain.impl.ExtBaseAmountDtoAssembler"> <property name="baseAmountFactory" ref="baseAmountFactory"/commerce-legacy/> </bean>
Follow the Commerce Manger extension guidelines and ensure that your extension plugin is started with the webapp, and that the plugin's MANIFEST.MF uses the com.elasticpath.cmclient.core package to extend the ModelCreator class, and com.elasticpath.cmclient.pricelistmanager package for the table and dialog extensions.
Extending Tables
Tables can be extended by adding a column heading and column values. You cannot add an entirely new table to Commerce Manager, only extend an existing table.
To extend a table, implement EPTableCreator and implement its methods:
ExampleTable implements EPTableCreator { ... }
Extending Sections
Sections should extend com.elasticpath.cmclient.core.editors.AbstractCmClientEditorPageSectionPart.
Section extensions should also implement com.elasticpath.cmclient.core.helpers.extenders.EpSectionCreator as a static inner class, Creator. Creator's one method, instantiateSection(), should return an instance of your extended section:
ExampleSection extends AbstractCmClientEditorPageSectionPart { ... public static class Creator implements EpSectionCreator { public AbstractCmClientFormSectionPart instantiateSection(FormPage formPage, AbstractCmClientFormEditor abstractCmClientFormEditor) { return new ExampleSection(...); } } }
Extending Pages
Pages should extend com.elasticpath.cmclient.core.editors.AbstractCmClientEditorPage.
Page extensions should also implement com.elasticpath.cmclient.core.helpers.extenders.EpPageCreator as a static inner class, Creator. Creator's one method, instantiatePage(), should return an instance of your extended page:
ExamplePage extends AbstractCmClientEditorPage { ... public static class Creator implements EpPageCreator { public AbstractCmClientEditorPage instantiatePage(AbstractCmClientFormEditor abstractCmClientFormEditor) { return new ExamplePage(...); } } }
Extending Dialogs
Dialogs should implement com.elasticpath.cmclient.core.helpers.extenders.DialogExtension and its methods:
public class ExampleDialog implements DialogExtension { ... }
Extending State Policy Determiners
State Policy Determiner extensions should implement com.elasticpath.cmclient.policy.StateDeterminer and its method, determineState(). determineState() accepts a PolicyActionContainer object and must return EpState.READ_ONLY, EpState.EDITABLE, or EpState.DISABLED:
public class ExampleDeterminer implements StateDeterminer { /** * Determine the state. * @param policyActionContainer * @return the state. */ public EpControlFactory.EpState determineState(PolicyActionContainer policyActionContainer) { return EpControlFactory.EpState.READ_ONLY; } }
For more details on creating or extending new state policies, see Creating a State Policy Extension Point.
Extending Promotion Rules
Rather than an outright extension of an existing promotion rule, promotions extensions typically take the form of adding a new kind of promotion rule to Commerce Manager. For more information on extending promotion rules, see Promotions.
Registering Your Plugin
Before starting up your extended plugin, you must reference it in the following files. The name you reference your plugin by is the Bundle-SymbolicName defined its META-INF/MANIFEST.MF file. After adding your plugin to the following files, rebuild your project using mvn clean install from commerce-extensions/.
META-INF/MANIFEST.MF
As with all OSGi bundles, your plugin must have a MANIFEST.MF file whit the following properties defined:
Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: table-examples Bundle-SymbolicName: pattern-catalog;singleton:=true Bundle-Version: 0.0.0.qualifier Bundle-Vendor: %providerName Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-ActivationPolicy: lazy Bundle-Localization: plugin Require-Bundle: org.eclipse.core.runtime, com.elasticpath.extensions.cm.ext-cm-libs, com.elasticpath.cmclient.policy, org.eclipse.core.databinding, org.eclipse.rap.ui, org.eclipse.rap.ui.forms
pom.xml
Your plugin should be listed in commerce-extensions/cm/ext-cm-plugins pom.xml file as a <module>:
<modules> <module>your-extended-plugin</module> ... </modules>
Extensible Classes in Commerce Manager
Tables
All extensible tables extend a class parented by com.elasticpath.cmclient.core.views.AbstractCmClientView.
Sections
All extensible sections extend a class parented by com.elasticpath.cmclient.core.editors.AbstractCmClientEditorPage.
Including non-OSGi Libraries and Dependencies
Any new plugins, or plugins not found in the existing out of the box Commerce Manager need to be included in the deployment files. If your plugin depends on non-OSGi bundles, or additional libs, these have to be included as well.
For detailed instructions on including non-OSGi bundles or other external dependencies, see Adding Non-Plugin Modules to Commerce Manager.