Customizing the promotion sequence builder

The promotion sequence builder is customized in the same manner as the AgendaBuilder.

  1. Implementing your Promotion Sequence Builder

    All custom sequence builders must implement the com.ibm.commerce.marketing.promotion.runtime.PromotionExecutionSequenceBuilder interface, which is a subclass of XMLizable. The key method of the sequence builder is the buildSequence method. It takes a PromotionContext object as input. A detailed discussion of the PromotionContext object can be found in the API documentation. You can customize the sequence builder if the current sequence building rules do not satisfy your requirements. A WebSphere Commerce instance has only one sequence builder and one agenda builder. Changes are common to all stores in the same instance.

    The following is a sample Sequence Builder. It is similar to the default sequence builder, except that it does not give priority to promotions for which a promotion code or coupon has been entered.

    package com.ibm.commerce.marketing.promotion.runtime;
    
    import java.util.Enumeration;
    import java.util.Vector;
    
    import org.w3c.dom.Node;
    
    import com.ibm.commerce.copyright.IBMCopyright;
    import com.ibm.commerce.marketing.promotion.Promotion;
    import com.ibm.commerce.marketing.promotion.group.PromotionGroup;
    import com.ibm.commerce.marketing.promotion.group.PromotionGroupKey;
    import com.ibm.commerce.marketing.promotion.xml.DeXMLizationException;
    import com.ibm.commerce.marketing.promotion.xml.XMLizationException;
    import com.ibm.commerce.marketing.util.XMLHelper;
    
    /**
     *A sequence builder for the promotion engine. The following rules are observed
     * 1. Promotions specified in a group that is defined earlier in the promotion
     *    invocation template are called before a promotion that is in a group defined
     *    later in the template.
     * 2. For promotions in the same group, when all else is equal, the one with a higher
     *    priority is invoked earlier than one that has a lower priority.
     *
     */
     
    public class StaticSequenceBuilder implements PromotionExecutionSequenceBuilder {
    
       /**
        * IBM Copyright
        */
       public static final String COPYRIGHT= IBMCopyright.SHORT_COPYRIGHT;
            
            
       /**
        * Constructor.
        *
        */ 
       public StaticSequenceBuilder() {
          super();
       }
    
       /**
        * Compares the priority of two promotions
        * @param promo1
        * @param promo2
        * @param context the current promotion context
        * @return >;0 when promo1 has precedence over promo2, =0,
        * promo1 and promo2 have the same priority, <0, promo2
        * takes precedence over promo1
        */
       protected int comparePromotionPriority(
          Promotion promo1,
          Promotion promo2,
          PromotionContext context) {
               
             PromotionGroupKey key1 = promo1.getGroupKey();
             PromotionGroupKey key2 = promo2.getGroupKey();
               
             PromotionGroup groups[] = context.getGroups();
             for (int i= 0; i < groups.length; i++) {
                if (groups[i].getKey().equals(key1)
                && (!groups[i].getKey().equals(key2))) {
                   return 1;
                }
                if (groups[i].getKey().equals(key2)
                   && (!groups[i].getKey().equals(key1))) {
                      return -1;
                   }
                }
               
                return promo1.getPriority().compareTo(promo2.getPriority());
             }
            
             /**
              * @see com.ibm.commerce.marketing.promotion.runtime.
              * PromotionExecutionSequenceBuilder#buildSequence(
              * com.ibm.commerce.marketing.promotion.runtime.PromotionContext)
              */
             public Vector buildSequence(PromotionContext context) {
                // calculate the sequence in which promotions will be evaluated
                Vector sequence = new Vector();
                Enumeration promos = context.listAllPromotions();
                while (promos.hasMoreElements()) {
                   Promotion promo = (Promotion) promos.nextElement();
                   boolean inserted = false;
                   for (int i = 0; i < sequence.size(); i++) {
                      if (comparePromotionPriority(promo,
                         (Promotion) sequence.elementAt(i),
                         context) > 0) {
                            sequence.insertElementAt(promo, i);
                            inserted = true;
                            break;
                      }
                   }
                   if (!inserted) {
                      sequence.addElement(promo);
                   }
                }
                return sequence;
             }
             
             /**
              * @see com.ibm.commerce.marketing.promotion.xml.XMLizable#toXML()
              */
             public String toXML() throws XMLizationException {
                StringBuffer buffer = new StringBuffer();
                buffer
                   .append("<PromotionExecutionSequenceBuilder impl=\"")
                   .append(this.getClass().getName())
                   .append("\"/>");
                   
                return buffer.toString();
             }
             
             
             /**
              * @see com.ibm.commerce.marketing.promotion.xml
              * .XMLizable#fromXML(org.w3c.dom.Node)
              */
             public void fromXML(Node anXMLNode) throws DeXMLizationException {
                try {
                   if this.getClass()
                      != Class.forName(
                      XMLHelper.getAttributeValue(anXMLNode,"impl"))) {
                         throw new DeXMLizationException("Wrong implementation");
                      }
                   } catch (DeXMLizationException e) {
                      throw e;
                   } catch (Throwable e) {
                      throw new DeXMLizationException(e.toString());
                   }
                }
                
             }
          }
    

  • Registering the custom sequence builder in the promotion engine configuration

    The following XML fragment in Promotion Engine configuration configures the sequence builder:

    <PromotionExecutionSequenceBuilder 
       impl="com.ibm.commerce.marketing.promotion.runtime.DefaultSequenceBuilder">
    

    Replace the impl attribute value with your fully qualified implementation class name of your new Sequence Builder.

  • Restarting WebSphere Commerce

    Since the agenda builder is initialized during WebSphere Commerce start up, a restart is required before the changes take effect.

    Related concepts