Easy Extension Framework v0.5 Help

Easy Item Types

Defining an easy item type

An easy item type definition can be created in easytypes.json manifest file. The manifest allows to define the following for an easy item type:

  • Code of the easy item type

  • Localized name of easy item type

  • Super type of the easy item type

  • Deployment information for easy item type

    • Deployment table name

    • Deployment type code

    • Props table name

  • Attributes for easy item type

    • Qualifier of the attribute

    • Localized name of the attribute

    • Persistence information of the attribute

      • Type of persistence

        • property for the database persistence

        • dynamic for the dynamic attribute

      • Name of the column for database persistence (property)

      • Bean reference for dynamic attribute's attributeHandler

    • Attribute modifiers

Example definition for a new easy item type

{ "code" : "EasyItem", "name" : [ { "lang" : "en", "value" : "Easy Item" } ], "autocreate" : "true", "generate": "true", "superType" : "GenericItem", "modelClassName": "EasyItemModel", "deployment" : { "table" : "easyitems", "typecode" : "25000" }, "attributes" : [ { "qualifier" : "code", "type" : "java.lang.String", "name" : [ { "lang" : "en", "value" : "Code" } ], "persistence" : { "type" : "property", "column" : "p_code" }, "modifiers" : { "unique" : "true", "initial" : "true", "optional" : "false", "write" : "false", "partof" : "false" } }, { "qualifier" : "name", "type" : "localized:java.lang.String", "name" : [ { "lang" : "en", "value" : "Name" } ], "persistence" : { "type" : "property", "column" : "p_name" }, "modifiers" : { "unique" : "false", "initial" : "false", "optional" : "true", "write" : "true", "partof" : "false" } }, { "qualifier" : "description", "type" : "localized:java.lang.String", "name" : [ { "lang" : "en", "value" : "Description" } ], "persistence" : { "type" : "property", "column" : "p_locprop" }, "modifiers" : { "unique" : "false", "initial" : "false", "optional" : "true", "write" : "true", "partof" : "false" } }, { "qualifier" : "mapAttribute", "type" : "TestEasyMap", "typeClass": "java.util.Map", "typeClassArguments": ["java.lang.String", "java.lang.String"], "name" : [ { "lang" : "en", "value" : "Map Attribute" } ], "persistence" : { "type" : "property", "column" : "p_mapattribute" }, "modifiers" : { "unique" : "false", "initial" : "false", "optional" : "true", "write" : "true", "partof" : "false" } } ] }

Example definition of extending an existing item type in easy item type

{ "itemtypes" : [ { "code" : "ExtendedCustomer", "name" : [ { "lang" : "en", "value" : "Extended Customer" } ], "superType" : "Customer", "modelClassName": "ExtendedCustomerModel", "attributes" : [ { "qualifier" : "testAttribute", "type" : "java.lang.String", "name" : [ { "lang" : "en", "value" : "Test Attribute" } ], "persistence" : { "type" : "property", "column" : "p_testAttribute" }, "modifiers" : { "unique" : "false", "initial" : "false", "optional" : "true", "write" : "true", "partof" : "false" } } ] } ] }

Example definition of adding attributes to an existing item type using easy item type

{ "code": "Customer", "attributes": [ { "qualifier": "testAttribute", "type": "java.lang.String", "name": [ { "lang": "en", "value": "Test Attribute" } ], "persistence": { "type": "property", "column": "p_testattribute" }, "modifiers": { "unique": "false", "initial": "false", "optional": "true", "write": "true", "partof": "false", "read": "true", "search": "false", "encrypted": "false" } } ] }

Defining the model class for an easy item type

Alternatively, The definition for the model class for an easy item type can be created by defining a Groovy class. Following considerations are important while defining a Groovy Model class:

  • The Groovy model class must be created inside the gensrc/main/groovy directory and inside the package <GROUP ID of your extension>/models

  • Extend your Groovy model class with the parent item type's model class

  • Create constants _TYPECODE for the easy item type having its value as the Code of easy item type

  • Create constants for the attributes defined in easy item type

  • Define a default constructor for your item making a super() call to call super class's default constructor

  • Defined a parameterized constructor with parameter as ItemModelContext to call super class's parameterized constructor accessing the ItemModelContext as parameter. For example: super(context)

Example definition of Groovy model class of a new easy item type

package com.sap.cx.boosters.easy.extension.easytype.model import de.hybris.bootstrap.annotations.Accessor import de.hybris.platform.core.model.ItemModel import de.hybris.platform.servicelayer.model.ItemModelContext class EasyItemModel extends ItemModel{ public static final String _TYPECODE = "EasyItem" public static final String CODE = "code" public static final String NAME = "name" public static final String DESCRIPTION = "description" EasyItemModel(){ super() } EasyItemModel(final ItemModelContext ctx) { super(ctx) } @Accessor(qualifier = CODE, type = Accessor.Type.GETTER) String getCode() { return getPersistenceContext().getPropertyValue(CODE) } @Accessor(qualifier = CODE, type = Accessor.Type.SETTER) void setCode(final String value) { getPersistenceContext().setPropertyValue(CODE, value) } @Accessor(qualifier = NAME, type = Accessor.Type.GETTER) String getName() { return getName(null) } @Accessor(qualifier = NAME, type = Accessor.Type.GETTER) String getName(final Locale loc) { return getPersistenceContext().getLocalizedValue(NAME, loc) } @Accessor(qualifier = NAME, type = Accessor.Type.SETTER) void setName(final String value) { setName(value, null) } @Accessor(qualifier = NAME, type = Accessor.Type.SETTER) void setName(final String value, final Locale loc) { getPersistenceContext().setLocalizedValue(NAME, loc, value) } @Accessor(qualifier = DESCRIPTION, type = Accessor.Type.GETTER) String getDescription() { return getDescription(null) } @Accessor(qualifier = DESCRIPTION, type = Accessor.Type.GETTER) String getDescription(final Locale loc) { return getPersistenceContext().getLocalizedValue(DESCRIPTION, loc) } @Accessor(qualifier = DESCRIPTION, type = Accessor.Type.SETTER) void setDescription(final String value) { setDescription(value, null) } @Accessor(qualifier = DESCRIPTION, type = Accessor.Type.SETTER) void setDescription(final String value, final Locale loc) { getPersistenceContext().setLocalizedValue(DESCRIPTION, loc, value) } }

Implementing the Attribute Handler for a dynamic attribute defined in easy item

When defining the easy item type with a dynamic attribute, the dynamic attribute requires a spring bean registered for the attribute handler. The attribute handler in an easy type can be implemented in four steps as:

  1. Define the dynamic attribute in easy item type definition as:

    { "itemtypes" : [ { "code" : "EasyItem", "name" : [ { "lang" : "en", "value" : "Easy Item" } ], "autocreate" : "true", "generate": "true", "superType" : "GenericItem", "deployment" : { "table" : "easyitems", "typecode" : "25000", "propstable" : "easyitemprops" }, "attributes" : [ { "qualifier" : "code", "type" : "java.lang.String", "name" : [ { "lang" : "en", "value" : "Code" } ], "persistence" : { "type" : "property", "column" : "p_code" }, "modifiers" : { "unique" : "true", "initial" : "true", "optional" : "false", "write" : "false", "partof" : "false" } }, { "qualifier" : "name", "type" : "localized:java.lang.String", "name" : [ { "lang" : "en", "value" : "Name" } ], "persistence" : { "type" : "property", "column" : "p_name" }, "modifiers" : { "unique" : "false", "initial" : "false", "optional" : "true", "write" : "true", "partof" : "false" } }, { "qualifier" : "description", "type" : "localized:java.lang.String", "name" : [ { "lang" : "en", "value" : "Description" } ], "persistence" : { "type" : "property", "column" : "p_locprop" }, "modifiers" : { "unique" : "false", "initial" : "false", "optional" : "true", "write" : "true", "partof" : "false" } }, { "qualifier" : "dynamicProperty", "type" : "java.lang.String", "name" : [ { "lang" : "en", "value" : "DynamicProperty" } ], "persistence" : { "type" : "dynamic", "attributeHandler" : "dynamicPropertyAttributeHandler" }, "modifiers" : { "write" : "false" } } ] } ] }
  2. Implement model class with getter for dynamicProperty (no setter as there is write="false" modifier for dynamicProperty)

    package com.sap.cx.boosters.easy.extension.easytype.model import de.hybris.bootstrap.annotations.Accessor import de.hybris.platform.core.model.ItemModel import de.hybris.platform.servicelayer.model.ItemModelContext class EasyItemModel extends ItemModel{ public static final String _TYPECODE = "EasyItem" public static final String CODE = "code" public static final String NAME = "name" public static final String DESCRIPTION = "description" public static final String DYNAMICPROPERTY = "dynamicProperty" EasyItemModel(){ super() } EasyItemModel(final ItemModelContext ctx) { super(ctx) } @Accessor(qualifier = CODE, type = Accessor.Type.GETTER) String getCode() { return getPersistenceContext().getPropertyValue(CODE) } @Accessor(qualifier = CODE, type = Accessor.Type.SETTER) void setCode(final String value) { getPersistenceContext().setPropertyValue(CODE, value) } @Accessor(qualifier = NAME, type = Accessor.Type.GETTER) String getName() { return getName(null) } @Accessor(qualifier = NAME, type = Accessor.Type.GETTER) String getName(final Locale loc) { return getPersistenceContext().getLocalizedValue(NAME, loc) } @Accessor(qualifier = NAME, type = Accessor.Type.SETTER) void setName(final String value) { setName(value, null) } @Accessor(qualifier = NAME, type = Accessor.Type.SETTER) void setName(final String value, final Locale loc) { getPersistenceContext().setLocalizedValue(NAME, loc, value) } @Accessor(qualifier = DESCRIPTION, type = Accessor.Type.GETTER) String getDescription() { return getDescription(null) } @Accessor(qualifier = DESCRIPTION, type = Accessor.Type.GETTER) String getDescription(final Locale loc) { return getPersistenceContext().getLocalizedValue(DESCRIPTION, loc) } @Accessor(qualifier = DESCRIPTION, type = Accessor.Type.SETTER) void setDescription(final String value) { setDescription(value, null) } @Accessor(qualifier = DESCRIPTION, type = Accessor.Type.SETTER) void setDescription(final String value, final Locale loc) { getPersistenceContext().setLocalizedValue(DESCRIPTION, loc, value) } @Accessor(qualifier = DYNAMICPROPERTY, type = Accessor.Type.GETTER) String getDynamicProperty() { return getPersistenceContext().getPropertyValue(DYNAMICPROPERTY) } }
  1. Implement the attribute handler

    package com.sap.cx.boosters.easy.easytype.attributehandler import package com.sap.cx.boosters.easy.extension.easytype.model.EasyTypeModel import de.hybris.platform.servicelayer.model.attribute.AbstractDynamicAttributeHandler import java.util.Date class DynamicPropertyAttributeHandler extends AbstractDynamicAttributeHandler{ @Override def get(def model) { def code = model.code def dynamicValue = code + new Date() return dynamicValue } }
  2. Register bean for attribute handler in EasyBeans.groovy

    import com.sap.cx.boosters.easy.easytype.attributehandler.DynamicPropertyAttributeHandler logger.info "[${extension.id}] registering Spring beans for core context" easyCoreBeans { dynamicPropertyAttributeHandler(DynamicPropertyAttributeHandler) } logger.info "[${extension.id}] registered Spring beans for core context"

Define the property to map the model class with an easy item type

  • To inform the model class of an easy item type to the easy extensibility framework, add the following property to easy.properties

    easytype.<Code of the Easy item type>.modelClass = <Fully qualified name of the model class>

Example of the easy item type to model class mapping (New Easy Item Type)

easytype.EasyItem.modelClass=com.sap.cx.boosters.easy.extension.easytype.model.EasyItemModel

Using easy item type in Groovy classes

While using the easy item types in the development of an easy extension the direct referencing can be used like we use these in standard commerce extensions. Following are some of the examples:

Creating a new instance of easy item type model

EasyItemModel easyItem = modelService.create(EasyItemModel) easyItem.code = "12345" easyItem.name = "My Easy Item" modelService.save(easyItem)

Setting property value

easyItem.setCode("12345") // OR easyItem.code = "12345"

Getting property value

String value = easyItem.getCode() // OR String value = easyItem.code

As method argument

def printEasyItem(EasyItemModel easyItem){ println(easyItem.code) println(easyItem.name) }

As method return value

EasyItemModel getItemForCode(String code){ List<EasyItemModel> items = easyItemDao.findItems() return null != items && items.size() > 0 ? items.get(0) : null }
EasyItemModel findItemByCode(String code){ def query = "SELECT {PK} FROM {EasyItem} WHERE {code}=?itemCode" EasyItemModel item = flexibleSearchService.searchUnique(query, [itemCode:code]) return item }

Using standard model class to get/set value of attribute defined via easy type

CustomerModel customer = (Customer) userService.getCurrentUser() String attributeValue = modelService.getAttributeValue(customer, "testAttribute") String newAttributeValue = "new " + attributeValue modelService.setAttributeValue(customer, "testAttribute", newAttributeValue)

Limitations with Easy Item Types

While the Easy item types can be defined at runtime, following points must be of the consideration while creating the Easy item types:

  • Cleanup of the Easy types is not supported as part of uninstall process for an easy extension.

Last modified: 18 August 2025