Page 1 of 1

Overriding AddressImpl

Posted: Sun Jul 06, 2014 4:27 pm
by mgarfi
I am trying to override the address implementation in broadleaf so that I can add a field, in this case a string named province. I am doing this by building on top of the heat clinic example site. I am currently having very strange issues with the checkout whereby the address are returned with all fields being null, however when saving the shipping details the address reappears.

Here are my customisations to the Heat Clinic demo.

Core Changes

I have started by working in the core module creating an ER_Address interface that extends Address, and an ER_AddressImpl which extends AddressImpl and implements ER_Address.

ER_Address

Code: Select all

public interface ER_Address extends Address{
    public String getProvince();
    public void setProvince(String province);
}


ER_AddressImplementation

Code: Select all

@Entity
@Table(name="ER_ADDRESS")
public class ER_AddressImpl extends AddressImpl implements ER_Address {

    private String province;

    @Override
    public String getProvince() {
        return province;
    }

    @Override
    public void setProvince(String province) {
        this.province = province;
    }
}

I then added the following entry to core:applicationContext-entity.xml

Code: Select all

<bean id="org.broadleafcommerce.profile.core.domain.Address" class="com.eggretail.domin.ER_AddressImpl" scope="prototype"/>



Site Changes

The next step is to work on the site module and this is where I currently come unstuck...

Firstly I edit the site:applicationContext-entity.xml file so it looks like this:

Code: Select all

<bean id="org.broadleafcommerce.profile.core.domain.Address" class="com.eggretail.domin.ER_AddressImpl" scope="prototype">
        <property name="country">
            <bean class="org.broadleafcommerce.profile.core.domain.CountryImpl">
                <property name="abbreviation" value="GB"/>
                <property name="name" value="Great Britain"/>
            </bean>
        </property>
    </bean>


Next I extend the BillingInfoForm and the ShippingInfoForm adding in my address implementation like this:

Code: Select all

public class ER_BillingInfoForm extends BillingInfoForm implements Serializable {

    private ER_Address er_address = new ER_AddressImpl();

    public ER_Address getAddress() {
        return er_address;
    }

    public void setAddress(ER_Address address) {
        this.er_address = address;
    }

}


Next I change the signatures on the controllers to use my Billing and Shipping forms. Then I extend the OnePageCheckoutProcessor and change all the instances of the forms to my implementation.

Any pointers on where I have gone wrong would be awesome!

Many thanks

Re: Overriding AddressImpl

Posted: Tue Jul 08, 2014 2:48 am
by phillipuniverse
Because the er_address on ER_BillingInfoForm is instantiated like new ER_AddressImpl(), that means that all of the fields on that address are set to null. When Spring goes to bind the form to that DTO, it only binds the values that were put in on the form. Since nothing about that looks up the org.broadleafcommerce....Address bean.

I'm not sure if that answers your question but that might be the starting point for why things are null. You might want to look into an @InitBinder like from: http://raymondhlee.wordpress.com/2011/0 ... ontroller/. We have an example of an @InitBinder in the demo site as well.

Re: Overriding AddressImpl

Posted: Fri Jul 18, 2014 11:30 am
by mgarfi
Hi Philipuniverse (mr universe perhaps? :) )

Thank you very much for these pointers they have been helpful in understanding the general flow of things. However I have still not managed to override the address implementation. My goal is simply an extra field on the registration form for a province, however I have ended up having to override/extend a lot.

I am now stuck on creating/extending the SinglePageCheckoutProcessor, I have followed the guidelines on creating a new dialect however I have been plagued by spring DI errors. I have worked through these editing the context:component-scan but have had to configure a hell of lot.. and its still not able to start up properly.

Here is the relevant part of the applicationContext.xml

Code: Select all

<!-- Configure custom checkout processor -->
    <context:component-scan base-package="org.broadleafcommerce.*">
        <context:include-filter type="regex" expression="org.broadleafcommerce.core.web.*" />
        <context:include-filter type="regex" expression="org.broadleafcommerce.openadmin.*" />
        <context:include-filter type="regex" expression="org.broadleafcommerce.openadmin.web.form.entity" />
        <context:exclude-filter type="regex" expression="org.broadleafcommerce.openadmin.web.form.ResetPasswordForm" />
    </context:component-scan>
    <bean id="blAdditionalSectionAuthorizations" class="org.springframework.beans.factory.config.ListFactoryBean" scope="prototype">
        <property name="sourceList">
            <list>
                <ref bean="blPolymorphicEntityCheckSectionAuthorization"/>
            </list>
        </property>
    </bean>

    <mo:override id="blMetadataOverrides">
        <mo:overrideItem configurationKey="targetProduct">
            <mo:field name="defaultCategory">
                <mo:property name="excluded" value="false"/>
            </mo:field>
            <mo:field name="id">
                <mo:property name="excluded" value="true"/>
            </mo:field>
            <mo:field name="description">
                <mo:property name="excluded" value="true"/>
            </mo:field>
            <mo:field name="longDescription">
                <mo:property name="excluded" value="true"/>
            </mo:field>
            <mo:field name="activeStartDate">
                <mo:property name="excluded" value="true"/>
            </mo:field>
            <mo:field name="activeEndDate">
                <mo:property name="excluded" value="true"/>
            </mo:field>
            <mo:field name="defaultCategory.activeStartDate">
                <mo:property name="excluded" value="true"/>
            </mo:field>
            <mo:field name="defaultCategory.activeEndDate">
                <mo:property name="excluded" value="true"/>
            </mo:field>
            <mo:field name="sku.name">
                <mo:property name="excluded" value="true"/>
            </mo:field>
            <mo:field name="sku.salePrice">
                <mo:property name="excluded" value="true"/>
            </mo:field>
            <mo:field name="sku.retailPrice">
                <mo:property name="excluded" value="true"/>
            </mo:field>
        </mo:overrideItem>
    </mo:override>

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" depends-on="blCacheManager">
        <property name="jpaVendorAdapter" ref="blJpaVendorAdapter"/>
        <property name="persistenceUnitManager" ref="blPersistenceUnitManager"/>
        <property name="persistenceUnitName" value="blPU"/>
    </bean>

    <bean id="blEJB3ConfigurationDao" class="org.broadleafcommerce.openadmin.server.dao.EJB3ConfigurationDaoImpl">
        <property name="persistenceUnitInfo">
            <bean factory-bean="entityManagerFactory" factory-method="getPersistenceUnitInfo" />
        </property>
    </bean>

    <bean id="blAppConfigurationMap" class="org.springframework.beans.factory.config.MapFactoryBean" scope="prototype">
        <property name="sourceMap">
            <map>
                <entry key="admin.showIfProperty.priceList" value="true"/>
            </map>
        </property>
    </bean>

    <bean id="checkoutProcessor" class="com.eggretail.seedBank.core.web.processor.ER_CheckoutProcessor" scope="prototype">
    </bean>

    <bean id="erDialect" class="com.eggretail.seedBank.core.web.processor.ER_Dialect">
        <property name="processors">
            <set>
                <ref bean="checkoutProcessor"/>
            </set>
        </property>
    </bean>

    <bean id="blWebTemplateEngine" class="org.thymeleaf.spring3.SpringTemplateEngine">
        <property name="dialects">
            <set>
                <ref bean="erDialect" />
            </set>
        </property>
    </bean>


I suspect I am going about this in the wrong way, any more pointers greatly appreciated!

Many thanks

Re: Overriding AddressImpl

Posted: Fri Jul 18, 2014 12:22 pm
by mgarfi
Ok so partially answering my own question incase anyone else has similar problems.

Following the instructions http://www.broadleafcommerce.com/docs/core/current/broadleaf-concepts/key-aspects-and-configuration/merge-configuration on merging contexts.

Code: Select all

<bean id="blOnePageCheckoutProcessor" class="com.eggretail.seedBank.core.web.processor.ER_CheckoutProcessor" scope="prototype"></bean>
<bean id="blDialectAdditionalProcessors" class="org.springframework.beans.factory.config.SetFactoryBean">
    <property name="sourceSet">
        <set>
            <ref bean="blOnePageCheckoutProcessor"/>
        </set>
    </property>
</bean>
<bean class="org.broadleafcommerce.common.extensibility.context.merge.LateStageMergeBeanPostProcessor">
    <property name="collectionRef" value="blDialectAdditionalProcessors" />
    <property name="targetRef" value="blDialectProcessors" />
</bean>


This then merges my custom processor into the blOnePageChekoutProcessor.

By extending the onePageCheckout and overwriting it/merging in the blc dialect I get all the injected items from the onePageCheckout and thus don't need lots of spring configuration to get it working.