10013---Trail ~ Catalogs

来源:互联网 发布:中国网络诗歌网 编辑:程序博客网 时间:2024/04/29 21:04

Introduction

A hybris catalog, as its name suggests, is similar to the concept of a printed catalog. It keeps a collection of your items together in one version. 

Unlike a printed catalog, however, hybris catalogs are dynamic, powerful and provide a high level of flexibilty. 

Catalogs allow you to update versions easily and permit to synchronize items from one catalog version to another, either by copying the entire catalog or by specifying attributes to be moved to another version.

One popular way to use catalogs is to have a staging and an online catalog containing identical products

. Products are kept in the staging catalog until considered ready for general release and are then synchronized into the online catalog version.

 Products in the staging catalog are still available in the live system, but are only visible to administrators or to authorized users

 with appropriate personalization settings. As soon as products are considered ready for release,

 the catalog version can be updated and (all or selected) items are synchronized to the online catalog version.

 Restrictions can be set up, so customers can only view Products in the online catalog whereas users may only edit products which are part of

 the staging catalog. This way a staging or testing environment can be set up allowing us to view Products, 

add them to shopping carts etc. before they are finally released to customers.

Motivation

In our example, we are going to demonstrate the use of Catalogs as a versioning system by making the News item 

in our Cuppy application catalog aware. The administrator adds News items in a staging mode first, 

so the news item is only released after having been proof-read and checked for consistency.

To implement a News item that can be staged and later released, we need to:

  • Make the News Type catalog aware in the items.xml of the CuppyTrail, so that we can set a catalog version on it
  • Create a News item with the catalog version (and id) and set the version to be Default:Staged initially
  • Synchronize the News Item so that we have an online catalog version of the News Item
  • View the read / write permissions of the News Item in the cuppy admin panel and notice that the News items in the online catalog are read-only
  • Login to the cuppy frontend and you will notice that no restrictions are in place meaning that both versions of the News item are visible
  • Add a Personalisation Rule for type News and user group cuppyplayers so that only News items of the online catalog version are visible

Tasks/Discussion

  • Make the News type catalog aware
  • Create a News item
  • Synchronize the News Item
  • Log into the cuppy cockpit and observe that no restrictions are in place yet
  • Add a Personalisation Rule for the News type and user group cuppyplayers
  • Compatibility issues

Make the News type catalog aware

We need to make the News type "catalog aware", so that we can associate it with a catalog and a catalog version. We do this by appending the two attributes catalogItemType and catalogVersionAttributeQualifier to the original definition of News. Note that we specify generate="false" because News is declared in the Cuppy extension already. We need to specify optional="false" since we need to specify the two attributes when we are creating a catalog aware News item.

Add the following XML fragment to the cuppytrail-items.xml in the items.xml

<itemtype        code="News"    autocreate="false"    generate="false">    <custom-properties>        <property name="catalogItemType"><value>java.lang.Boolean.TRUE</value></property>        <property name="catalogVersionAttributeQualifier"><value>"catalogVersion"</value></property>        <property name="uniqueKeyAttributeQualifier"><value>"id"</value></property>    </custom-properties>    <attributes>        <attribute qualifier="id" type="java.lang.String">            <modifiers initial="true" optional="false" write="true"/>            <persistence type="property"/>            </attribute>        <attribute qualifier="catalogVersion" type="CatalogVersion">            <modifiers initial="true" optional="false" write="true"/>            <persistence type="property"/>        </attribute>    </attributes></itemtype>
cuppytrail/resources/localization/cuppytrail-locales_en.properties
type.news.catalogVersion.name=Catalog Versiontype.news.catalogVersion.description=Catalog Version of the News Item type.news.id.name=idtype.news.id.description=unique identifier used by catalogs
Rebuild your project (ant all). Since the data model and localization has changed, 

we also need update the system (Update running system and Localize types).

Create a News item

Login to cuppy at http://localhost:9001/cuppy, using the login pp and password 1234. Change to the admin perspective.
Now select News type from the console on the left and create a new News Item. You will notice that you get a dialog box displaying all mandatory fields you need to fill in. These are the Catalog ID and Catalog version.


---

Choose the existing Catalog version of "Staged" and add a unique identifier (e.g. "111"). Add all essential details and then click

 on the done button to add a new News Item. Use the tab on the right to click on the "message" field and edit the Message field. 

We had added the text "The women's world cup is over"

----

Logout of cuppy and log back in as a CuppY player using the login demo_cuppy and password 1234

and notice that you can now see the news Item. However, this is not the behavior we want and we

 still need to set up staging/online visibiltiy and access rights.

---

Synchronize the News Item

Before we add personalization rules to filter the players' views, we need to synchronize the News item to have an online and a staging version. 

This will make it easier to see the personalization rules in effect when we create them. In the real world, your personalization rules 

would need to be set up initially, and you would perform synchronization at regular intervals according to your requirements. 

In our trail, we want to emphasize the different behavior of Items which reside in different version, that is why we are performing a synchronization first.

To synchronize the News Item, we first need to add it to the Synchronization rule. A Synchronization rule will only synchronize types 

that it is told about:

Open the hMC console at http://localhost:9001/hmc/hybris and log in with login admin, password nimda

Open the Catalog tree element on the left. Choose catalogs, open the default catalog Item and the default catalog type.

Choose the Default Staged Catalog version and click the synchronize catalog version on the top right to open the Synchronization wizard.
Then select theTarget tab, double click on the Synchronization with code Synch Default:Staged to Default:Online

Add News to the list of Root Types in the Type Setting list at the bottom of the page, 

    by right clicking on the list and using the +Add Composed Type.

---

In the “identifier” field at the top, type “News” and do a search. Select the News Item from the result and click “use”. 

Now save and then click the small green start button on the bottom right of the Synchronization wizard pane.


You should get a pop-up success message. Now login to cuppy as the pp user and select the Admin page. 

Choose News from the types on the left and you will see that you have two News items in the system. 

If you double click on them alternatively and compare them by looking at the information on the right, 

you will see that there is a staging and an online catalog version. Click on the message

 field and you will see that the online version cannot be modified. This is because we are using

 the default Catalog which has a staging and online version already. By default these are editable and 

non editable respectively which is what you usually want.

Log into the cuppy cockpit and observe that no restrictions are in place yet

If you login login demo_cuppy and password 1234, you will see that there are two News Items visible to the user.

To prevent the user from seeing the staged news item, we need to set up a personalization rule.

--

Add a Personalisation Rule for the News type and user group cuppyplayers

We'll add the rule with impex

Open the hMC, choose System from the tree on the left, select Personalization and then specify the fields as follows: fill in the Identifier: Cuppy_Frontend_News, Name: News, Filter: {item:catalogVersion} IN (?session.catalogversions), Restricted Type: News - News, 

Apply on: cuppyplayers

---

This rule (or restriction) checks the catalogVersion variable against the session to make sure that only version values

 that match those in the session will be returned.

For making it persistent include the equivalent impex file:

/cuppytrail/resources/impex/essentialdataSearchRestriction.impex
INSERT_UPDATE SearchRestriction;code[unique=true]; name[lang=en];query;restrictedType(code);principal(uid);generate[default=true];active[default=true];Cuppy_Frontend_News;News;"{item:catalogVersion} IN (?session.catalogversions)";News;cuppyplayers


The second part of getting this filter to work properly is to set the value of the catalogVersion. 

This is done by extending the DefaultMatchService class with the CuppytrailMatchService class and overriding the getLatestNews() method. 

You will see that we use an anonymous inner class SessionExecutionBody. The details of this are outside of the scope of this trail.

 If we didn't do this, the catalog version filtering would be applied to all of the items in the system and not just News


Add the following piece of xml to the cuppytrail-spring.xml file:

<bean id="matchService" class="de.hybris.platform.cuppytrail.CuppytrailMatchService"/>
Rebuild your system (ant all) and run an update in the hybris Administration Console (essential data) to load the search restrictions 

we created in the impex file above. Once complete, log back in to the Cuppy application using the login demo_cuppy and password 1234,

 and you will see a single News item being displayed. This is the online version as we intended. 

News items created in the staged catalog version will not be visible until they are synchronized to the catalog's online version.

Compatibility issues

Since we have changed News type as Catalog aware type we need to refactor all places in the code where News items are automatically

created (e.g. Trail ~ Events), since id and catalogVersion are mandatory. For that reason we add a PrepareInterceptor

 which generates the id and sets the catalog Version before a News item is saved.

Create an additional Interceptor class NewsCatalogAwareInterceptor

NewsCatalogAwareInterceptor creates NewsModel with predefined catalog version and generated keys for newsId.

src/de/hybris/platform/cuppytrail/interceptors/NewsCatalogAwareInterceptor.java
package de.hybris.platform.cuppytrail.interceptors;
 
import de.hybris.platform.catalog.CatalogVersionService;
import de.hybris.platform.catalog.model.CatalogVersionModel;
import de.hybris.platform.cuppy.model.NewsModel;
import de.hybris.platform.servicelayer.interceptor.InterceptorContext;
import de.hybris.platform.servicelayer.interceptor.InterceptorException;
import de.hybris.platform.servicelayer.interceptor.PrepareInterceptor;
import de.hybris.platform.servicelayer.keygenerator.KeyGenerator;
 
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Required;
 
 
/**
 * Adds default catalog version and default ID in case no catalog version or no ID is set.
 */
public class NewsCatalogAwareInterceptor implements PrepareInterceptor
{
    private String defaultCatalog;
    private String defaultCatalogVersion;
    private CatalogVersionService catalogVersionService;
    private KeyGenerator keyGenerator;
 
    @Override
    public void onPrepare(final Object model, final InterceptorContext ctx) throws InterceptorException
    {
        if (model instanceof NewsModel)
        {
            final NewsModel news = (NewsModel) model;
 
            if (StringUtils.isBlank(news.getId()))
            {
                news.setId(createNewsId());
            }
 
            if (news.getCatalogVersion() == null)
            {
                news.setCatalogVersion(getDefaultCatalogVersion());
            }
        }
    }
 
    private String createNewsId()
    {
        return this.keyGenerator.generate().toString();
    }
 
    private CatalogVersionModel getDefaultCatalogVersion()
    {
        return this.catalogVersionService.getCatalogVersion(this.defaultCatalog, this.defaultCatalogVersion);
    }
 
    @Required
    public void setDefaultCatalog(final String defaultCatalog)
    {
        this.defaultCatalog = defaultCatalog;
    }
 
    @Required
    public void setDefaultCatalogVersion(final String defaultCatalogVersion)
    {
        this.defaultCatalogVersion = defaultCatalogVersion;
    }
 
    @Required
    public void setKeyGenerator(final KeyGenerator keyGenerator)
    {
        this.keyGenerator = keyGenerator;
    }
 
    @Required
    public void setCatalogVersionService(final CatalogVersionService catalogVersionService)
    {
        this.catalogVersionService = catalogVersionService;
    }
}
package de.hybris.platform.cuppytrail.interceptors; import de.hybris.platform.catalog.CatalogVersionService;import de.hybris.platform.catalog.model.CatalogVersionModel;import de.hybris.platform.cuppy.model.NewsModel;import de.hybris.platform.servicelayer.interceptor.InterceptorContext;import de.hybris.platform.servicelayer.interceptor.InterceptorException;import de.hybris.platform.servicelayer.interceptor.PrepareInterceptor;import de.hybris.platform.servicelayer.keygenerator.KeyGenerator; import org.apache.commons.lang.StringUtils;import org.springframework.beans.factory.annotation.Required;  /** * Adds default catalog version and default ID in case no catalog version or no ID is set. */public class NewsCatalogAwareInterceptor implements PrepareInterceptor{    private String defaultCatalog;    private String defaultCatalogVersion;    private CatalogVersionService catalogVersionService;    private KeyGenerator keyGenerator;     @Override    public void onPrepare(final Object model, final InterceptorContext ctx) throws InterceptorException    {        if (model instanceof NewsModel)        {            final NewsModel news = (NewsModel) model;             if (StringUtils.isBlank(news.getId()))            {                news.setId(createNewsId());            }             if (news.getCatalogVersion() == null)            {                news.setCatalogVersion(getDefaultCatalogVersion());            }        }    }     private String createNewsId()    {        return this.keyGenerator.generate().toString();    }     private CatalogVersionModel getDefaultCatalogVersion()    {        return this.catalogVersionService.getCatalogVersion(this.defaultCatalog, this.defaultCatalogVersion);    }     @Required    public void setDefaultCatalog(final String defaultCatalog)    {        this.defaultCatalog = defaultCatalog;    }     @Required    public void setDefaultCatalogVersion(final String defaultCatalogVersion)    {        this.defaultCatalogVersion = defaultCatalogVersion;    }     @Required    public void setKeyGenerator(final KeyGenerator keyGenerator)    {        this.keyGenerator = keyGenerator;    }     @Required    public void setCatalogVersionService(final CatalogVersionService catalogVersionService)    {        this.catalogVersionService = catalogVersionService;    }}

Spring

Open the file cuppytrail/resources/cuppytrail-spring.xml. Add the following beans definition to it:

cuppytrail/resources/cuppytrail-spring.xml
<bean id="newsCatalogAwareInterceptor" class="de.hybris.platform.cuppytrail.interceptors.NewsCatalogAwareInterceptor" autowire="byName">        <property name="keyGenerator" ref="newsIdGenerator" />        <property name="defaultCatalog" value="Default" />        <property name="defaultCatalogVersion" value="Online" />        <property name="catalogVersionService" ref="catalogVersionService" />    </bean>        <bean id="NewsValidateInterceptorMapping" class="de.hybris.platform.servicelayer.interceptor.impl.InterceptorMapping">        <property name="interceptor" ref="newsCatalogAwareInterceptor" />        <property name="typeCode" value="News" />    </bean>     <bean id="newsIdGenerator" class="de.hybris.platform.servicelayer.keygenerator.impl.PersistentKeyGenerator" init-method="init">        <property name="key" value="news_id" />        <property name="digits" value="8" />        <property name="start" value="00000000" />        <property name="numeric" value="true" />    </bean>




0 0