You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ofbiz.apache.org by David E Jones <jo...@apache.org> on 2009/03/06 18:19:10 UTC

Re: svn commit: r750878 - in /ofbiz/trunk: applications/product/webapp/catalog/WEB-INF/controller.xml applications/product/webapp/catalog/product/ProductForms.xml framework/webapp/src/org/ofbiz/webapp/event/ServiceVariantsEventHandler.java

Please revert this patch:

1. the ServiceVariantEventHandler is in the framework and is dependent  
on the applications/product component

2. creating an event handler for this is pure silliness in the first  
place and should simply be done with a custom event

-David


On Mar 6, 2009, at 5:41 AM, jleroux@apache.org wrote:

> Author: jleroux
> Date: Fri Mar  6 12:41:38 2009
> New Revision: 750878
>
> URL: http://svn.apache.org/viewvc?rev=750878&view=rev
> Log:
> A modified patch from Eric De Maulde "When a virtual product is  
> modified, its variants aren't modified" (https://issues.apache.org/jira/browse/OFBIZ-2228 
> ) - OFBIZ-2228
> Also I removed an update link from Product suppliers lists (not  
> fields were modifiable)
> More formatting to come (but in all OFBiz, ie no only in  
> ServiceVariantsEventHandler.java)
>
> Added:
>    ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/event/ 
> ServiceVariantsEventHandler.java
> Modified:
>    ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/ 
> controller.xml
>    ofbiz/trunk/applications/product/webapp/catalog/product/ 
> ProductForms.xml
>
> Modified: ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/ 
> controller.xml
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/controller.xml?rev=750878&r1=750877&r2=750878&view=diff
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/ 
> controller.xml (original)
> +++ ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/ 
> controller.xml Fri Mar  6 12:41:38 2009
> @@ -25,6 +25,7 @@
>     <owner>Copyright 2001-2008 The Apache Software Foundation</owner>
>
>     <handler name="service-multi" type="request"  
> class="org.ofbiz.webapp.event.ServiceMultiEventHandler"/>
> +    <handler name="service-variant" type="request"  
> class="org.ofbiz.webapp.event.ServiceVariantsEventHandler"/>
>     <handler name="groovy" type="request"  
> class="org.ofbiz.webapp.event.GroovyEventHandler"/>
>
>     <firstvisit></firstvisit>
> @@ -536,19 +537,19 @@
>     </request-map>
>     <request-map uri="createProductPrice">
>         <security https="true" auth="true"/>
> -        <event type="service" path="" invoke="createProductPrice"/>
> +        <event type="service-variant" path=""  
> invoke="createProductPrice"/>
>         <response name="success" type="view"  
> value="EditProductPrices"/>
>         <response name="error" type="view" value="EditProductPrices"/>
>     </request-map>
>     <request-map uri="updateProductPrice">
>         <security https="true" auth="true"/>
> -        <event type="service" path="" invoke="updateProductPrice"/>
> +        <event type="service-variant" path=""  
> invoke="updateProductPrice"/>
>         <response name="success" type="view"  
> value="EditProductPrices"/>
>         <response name="error" type="view" value="EditProductPrices"/>
>     </request-map>
>     <request-map uri="deleteProductPrice">
>         <security https="true" auth="true"/>
> -        <event type="service" path="" invoke="deleteProductPrice"/>
> +        <event type="service-variant" path=""  
> invoke="deleteProductPrice"/>
>         <response name="success" type="view"  
> value="EditProductPrices"/>
>         <response name="error" type="view" value="EditProductPrices"/>
>     </request-map>
> @@ -738,19 +739,19 @@
>     </request-map>
>     <request-map uri="addProductToCategory">
>         <security https="true" auth="true"/>
> -        <event type="service" path=""  
> invoke="safeAddProductToCategory"/>
> +        <event type="service-variant" path=""  
> invoke="safeAddProductToCategory"/>
>         <response name="success" type="view"  
> value="EditProductCategories"/>
>         <response name="error" type="view"  
> value="EditProductCategories"/>
>     </request-map>
>     <request-map uri="updateProductToCategory">
>         <security https="true" auth="true"/>
> -        <event type="service" path=""  
> invoke="updateProductToCategory"/>
> +        <event type="service-variant" path=""  
> invoke="updateProductToCategory"/>
>         <response name="success" type="view"  
> value="EditProductCategories"/>
>         <response name="error" type="view"  
> value="EditProductCategories"/>
>     </request-map>
>     <request-map uri="removeProductFromCategory">
>         <security https="true" auth="true"/>
> -        <event type="service" path=""  
> invoke="removeProductFromCategory"/>
> +        <event type="service-variant" path=""  
> invoke="removeProductFromCategory"/>
>         <response name="success" type="view"  
> value="EditProductCategories"/>
>         <response name="error" type="view"  
> value="EditProductCategories"/>
>     </request-map>
> @@ -2273,7 +2274,7 @@
>     <request-map uri="EditProductSuppliers"><security https="true"  
> auth="true"/><response name="success" type="view"  
> value="EditSupplierProduct"/></request-map>
>     <request-map uri="createSupplierProduct">
>         <security https="true" auth="true"/>
> -        <event type="service" path=""  
> invoke="createSupplierProduct"/>
> +        <event type="service-variant" path=""  
> invoke="createSupplierProduct"/>
>         <response name="success" type="view"  
> value="EditSupplierProduct"/>
>         <response name="error" type="view"  
> value="EditSupplierProduct"/>
>     </request-map>
> @@ -2285,7 +2286,7 @@
>     </request-map>
>     <request-map uri="removeSupplierProduct">
>         <security https="true" auth="true"/>
> -        <event type="service" path=""  
> invoke="removeSupplierProduct"/>
> +        <event type="service-variant" path=""  
> invoke="removeSupplierProduct"/>
>         <response name="success" type="view"  
> value="EditSupplierProduct"/>
>         <response name="error" type="view"  
> value="EditSupplierProduct"/>
>     </request-map>
> @@ -2314,19 +2315,19 @@
>     <request-map uri="ProductConfigItemArticle"><security  
> https="true" auth="true"/><response name="success" type="view"  
> value="ProductConfigItemArticle"/></request-map>
>     <request-map uri="createProductConfig">
>         <security https="true" auth="true"/>
> -        <event type="service" path="" invoke="createProductConfig"/>
> +        <event type="service-variant" path=""  
> invoke="createProductConfig"/>
>         <response name="success" type="view"  
> value="EditProductConfigs"/>
>         <response name="error" type="view"  
> value="EditProductConfigs"/>
>     </request-map>
>     <request-map uri="updateProductConfig">
>         <security https="true" auth="true"/>
> -        <event type="service" path="" invoke="updateProductConfig"/>
> +        <event type="service-variant" path=""  
> invoke="updateProductConfig"/>
>         <response name="success" type="view"  
> value="EditProductConfigs"/>
>         <response name="error" type="view"  
> value="EditProductConfigs"/>
>     </request-map>
>     <request-map uri="deleteProductConfig">
>         <security https="true" auth="true"/>
> -        <event type="service" path="" invoke="deleteProductConfig"/>
> +        <event type="service-variant" path=""  
> invoke="deleteProductConfig"/>
>         <response name="success" type="view"  
> value="EditProductConfigs"/>
>         <response name="error" type="view"  
> value="EditProductConfigs"/>
>     </request-map>
>
> Modified: ofbiz/trunk/applications/product/webapp/catalog/product/ 
> ProductForms.xml
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/webapp/catalog/product/ProductForms.xml?rev=750878&r1=750877&r2=750878&view=diff
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- ofbiz/trunk/applications/product/webapp/catalog/product/ 
> ProductForms.xml (original)
> +++ ofbiz/trunk/applications/product/webapp/catalog/product/ 
> ProductForms.xml Fri Mar  6 12:41:38 2009
> @@ -384,6 +384,12 @@
>                 </entity-options>
>             </drop-down>
>         </field>
> +        <field name="modifyVariants" title="Modify Variants">
> +            <drop-down allow-empty="false" no-current-selected- 
> key="N">
> +                <option key="Y" description="${uiLabelMap.CommonY}"/>
> +                <option key="N" description="${uiLabelMap.CommonN}"/>
> +            </drop-down>
> +        </field>
>         <field name="submitButton" title="$ 
> {uiLabelMap.CommonCreate}" widget-style="smallSubmit"><submit button- 
> type="button"/></field>
>     </form>
>     <form name="UpdateProductPrice" type="list"  
> target="updateProductPrice" title="" list-name="productPrices"
> @@ -471,6 +477,12 @@
>         <field name="sequenceNum" title="$ 
> {uiLabelMap.ProductSequenceNum}" ></field>
>         <field name="quantity" title="${uiLabelMap.ProductQuantity}"  
> ></field>
>         <field name="comments" ><textarea/></field>
> +        <field name="modifyVariants" title="Modify Variants">
> +            <drop-down allow-empty="false" no-current-selected- 
> key="N">
> +                <option key="Y" description="${uiLabelMap.CommonY}"/>
> +                <option key="N" description="${uiLabelMap.CommonN}"/>
> +            </drop-down>
> +        </field>
>         <field name="submitButton" title="${uiLabelMap.CommonAdd}"  
> widget-style="smallSubmit"><submit button-type="button"/></field>
>     </form>
>     <form name="UpdateProductCategoryMemeber" type="list"  
> target="updateProductToCategory" title="" list- 
> name="productCategoryMembers"
> @@ -820,6 +832,12 @@
>                 <option key="N" description="${uiLabelMap.CommonN}"/>
>             </drop-down>
>         </field>
> +        <field name="modifyVariants" title="Modify Variants">
> +            <drop-down allow-empty="false" no-current-selected- 
> key="N">
> +                <option key="Y" description="${uiLabelMap.CommonY}"/>
> +                <option key="N" description="${uiLabelMap.CommonN}"/>
> +            </drop-down>
> +        </field>
>         <field use-when="supplierProduct == null"  
> name="submitButton" title="${uiLabelMap.CommonCreate}"><submit  
> button-type="button"/></field>
>         <field use-when="supplierProduct != null"  
> name="submitButton" title="${uiLabelMap.CommonUpdate}"><submit  
> button-type="button"/></field>
>     </form>
> @@ -849,10 +867,11 @@
>             header-link="EditProductSuppliers?productId=$ 
> {productId}&amp;orderBy=lastPrice" header-link-style="buttontext">
>                 <display type="currency" currency="${currencyUomId}"/>
>         </field>
> -        <field name="updateLink" title="$ 
> {uiLabelMap.CommonEmptyHeader}" widget-style="buttontext">
> +        <!-- not usable : no fields modifiable -->
> +        <!--field name="updateLink" title="$ 
> {uiLabelMap.CommonEmptyHeader}" widget-style="buttontext">
>             <hyperlink target="EditProductSuppliers?productId=$ 
> {productId}&amp;partyId=${partyId}&amp;currencyUomId=$ 
> {currencyUomId}&amp;minimumOrderQuantity=$ 
> {minimumOrderQuantity}&amp;availableFromDate=${availableFromDate}"
>                 description="${uiLabelMap.CommonUpdate}" also- 
> hidden="false"/>
> -        </field>
> +        </field-->
>         <field name="deleteLink" title="$ 
> {uiLabelMap.CommonEmptyHeader}" widget-style="buttontext">
>             <hyperlink target="removeSupplierProduct?productId=$ 
> {productId}&amp;partyId=${partyId}&amp;currencyUomId=$ 
> {currencyUomId}&amp;minimumOrderQuantity=$ 
> {minimumOrderQuantity}&amp;availableFromDate=${availableFromDate}"
>                 description="${uiLabelMap.CommonDelete}" also- 
> hidden="false"/>
> @@ -877,6 +896,12 @@
>                 </entity-options>
>             </drop-down>
>         </field>
> +        <field name="modifyVariants" title="Modify Variants">
> +            <drop-down allow-empty="false" no-current-selected- 
> key="N">
> +                <option key="Y" description="${uiLabelMap.CommonY}"/>
> +                <option key="N" description="${uiLabelMap.CommonN}"/>
> +            </drop-down>
> +        </field>
>         <field name="submitButton" title="$ 
> {uiLabelMap.CommonCreate}" widget-style="smallSubmit"><submit button- 
> type="button"/></field>
>     </form>
>     <form name="UpdateProductConfig" type="list"  
> target="updateProductConfig" title="" list-name="productConfigs"
>
> Added: ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/event/ 
> ServiceVariantsEventHandler.java
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/event/ServiceVariantsEventHandler.java?rev=750878&view=auto
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/event/ 
> ServiceVariantsEventHandler.java (added)
> +++ ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/event/ 
> ServiceVariantsEventHandler.java Fri Mar  6 12:41:38 2009
> @@ -0,0 +1,433 @@
> +/ 
> *******************************************************************************
> + * /Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements.  See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership.  The ASF licenses this file
> + * to you under the Apache License, Version 2.0 (the
> + * "License"); you may not use this file except in compliance
> + * with the License.  You may obtain a copy of the License at
> + *
> + * http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,
> + * software distributed under the License is distributed on an
> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> + * KIND, either express or implied.  See the License for the
> + * specific language governing permissions and limitations
> + * under the License.
> +  
> *******************************************************************************/
> +package org.ofbiz.webapp.event;
> +
> +import java.util.Arrays;
> +import java.util.List;
> +import java.util.Locale;
> +import java.util.Map;
> +import java.util.TimeZone;
> +
> +import javax.servlet.ServletContext;
> +import javax.servlet.http.HttpServletRequest;
> +import javax.servlet.http.HttpServletResponse;
> +import javax.servlet.http.HttpSession;
> +
> +import javolution.util.FastList;
> +import javolution.util.FastMap;
> +
> +import org.ofbiz.base.util.Debug;
> +import org.ofbiz.base.util.UtilHttp;
> +import org.ofbiz.base.util.UtilMisc;
> +import org.ofbiz.base.util.UtilProperties;
> +import org.ofbiz.base.util.UtilValidate;
> +import org.ofbiz.entity.GenericValue;
> +import org.ofbiz.entity.transaction.GenericTransactionException;
> +import org.ofbiz.entity.transaction.TransactionUtil;
> +import org.ofbiz.service.DispatchContext;
> +import org.ofbiz.service.GenericServiceException;
> +import org.ofbiz.service.LocalDispatcher;
> +import org.ofbiz.service.ModelParam;
> +import org.ofbiz.service.ModelService;
> +import org.ofbiz.service.ServiceAuthException;
> +import org.ofbiz.service.ServiceUtil;
> +import org.ofbiz.service.ServiceValidationException;
> +import org.ofbiz.webapp.control.ConfigXMLReader;
> +import org.ofbiz.webapp.control.RequestHandler;
> +
> +/**
> + * ServiceVariantsEventHandler - Event handler for running a  
> service multiple times, over all variant related to the virtual  
> product
> + */
> +public class ServiceVariantsEventHandler implements EventHandler {
> +
> +    public static final String module =  
> ServiceVariantsEventHandler.class.getName();
> +
> +    public static final String SYNC = "sync";
> +    public static final String ASYNC = "async";
> +
> +    protected ServletContext servletContext;
> +
> +    /**
> +     * @see  
> org.ofbiz.webapp.event.EventHandler#init(javax.servlet.ServletContext)
> +     */
> +    public void init(ServletContext servletContext) throws  
> EventHandlerException {
> +        this.servletContext = servletContext;
> +    }
> +
> +    /**
> +     * @see  
> org.ofbiz.webapp.event.EventHandler#invoke(java.lang.String,  
> java.lang.String, javax.servlet.http.HttpServletRequest,  
> javax.servlet.http.HttpServletResponse)
> +     */
> +    public String invoke(String eventPath, String eventMethod,  
> HttpServletRequest request, HttpServletResponse response) throws  
> EventHandlerException {
> +        // TODO: consider changing this to use the new  
> UtilHttp.parseMultiFormData method
> +
> +        // make sure we have a valid reference to the Service Engine
> +        LocalDispatcher dispatcher = (LocalDispatcher)  
> request.getAttribute("dispatcher");
> +        if (dispatcher == null) {
> +            throw new EventHandlerException("The local service  
> dispatcher is null");
> +        }
> +        DispatchContext dctx = dispatcher.getDispatchContext();
> +        if (dctx == null) {
> +            throw new EventHandlerException("Dispatch context  
> cannot be found");
> +        }
> +
> +        // get the details for the service(s) to call
> +        String mode = SYNC;
> +        String serviceName = null;
> +
> +        if (eventPath == null || eventPath.length() == 0) {
> +            mode = SYNC;
> +        } else {
> +            mode = eventPath;
> +        }
> +
> +        // we only support SYNC mode in this handler
> +        if (!SYNC.equals(mode)) {
> +            throw new EventHandlerException("Async mode is not  
> supported");
> +        }
> +
> +        // nake sure we have a defined service to call
> +        serviceName = eventMethod;
> +        if (serviceName == null) {
> +            throw new EventHandlerException("Service name  
> (eventMethod) cannot be null");
> +        }
> +        if (Debug.verboseOn()) Debug.logVerbose("[Set mode/ 
> service]: " + mode + "/" + serviceName, module);
> +
> +        // some needed info for when running the service
> +        Locale locale = UtilHttp.getLocale(request);
> +        TimeZone timeZone = UtilHttp.getTimeZone(request);
> +        HttpSession session = request.getSession();
> +        GenericValue userLogin = (GenericValue)  
> session.getAttribute("userLogin");
> +
> +        // get the service model to generate context(s)
> +        ModelService modelService = null;
> +
> +        try {
> +            modelService = dctx.getModelService(serviceName);
> +        } catch (GenericServiceException e) {
> +            throw new EventHandlerException("Problems getting the  
> service model", e);
> +        }
> +
> +        if (modelService == null) {
> +            throw new EventHandlerException("Problems getting the  
> service model");
> +        }
> +
> +        if (Debug.verboseOn()) Debug.logVerbose("[Processing]:  
> SERVICE Event", module);
> +        if (Debug.verboseOn()) Debug.logVerbose("[Using delegator]:  
> " + dispatcher.getDelegator().getDelegatorName(), module);
> +
> +        // check if we are to also look in a global scope (no  
> delimiter)
> +        boolean checkGlobalScope =  
> request.getParameter("_checkGlobalScope") == null ? true :
> + 
>                 !"N 
> ".equalsIgnoreCase(request.getParameter("_checkGlobalScope"));
> +
> +        // get All Variant Products related to the Virtual Product
> +        String productId = new String();
> +        FastList<GenericValue> variantList = FastList.newInstance();
> +         
> if(UtilValidate.isNotEmpty(request.getParameter("productId"))) {
> +            productId = request.getParameter("productId");
> +            // check Virtual Current Product
> +            try{
> +                GenericValue product = (GenericValue)  
> dispatcher.runSync("getProduct", UtilMisc.toMap("productId",  
> productId)).get("product");
> +
> +                // check if we have to implement changes to all  
> Product Variants
> +                if(! 
> request.getParameterMap().containsKey("modifyVariants")
> +                   ||  
> request.getParameterMap().containsKey("modifyVariants")
> +                   &&  
> request.getParameter("modifyVariants").equals("Y")
> +                   &&  
> product.get("isVirtual").toString().equals("Y")) {
> +                    // save Variant Products
> +                    try {
> +                        Map<String, Object> variantMap =  
> dispatcher.runSync("getAllProductVariants",  
> UtilMisc.toMap("productId", productId));
> +                        if  
> (variantMap.get("responseMessage").equals("success") &&  
> variantMap.get("assocProducts") != null) {
> +                            FastList<GenericValue>  
> assocProductsList = (FastList<GenericValue>)  
> variantMap.get("assocProducts");
> +                            variantList.addAll(assocProductsList);
> +
> +                            // get Sub-Variant
> +                            for(GenericValue assocProduct:  
> assocProductsList){
> +                                try{
> +                                    GenericValue variant =  
> (GenericValue) dispatcher.runSync("getProduct",  
> UtilMisc.toMap("productId",  
> assocProduct.get("productIdTo"))).get("product");
> +                                     
> if(variant.get("isVirtual").toString().equals("Y")){
> +                                        // save Sub-Variant Products
> +                                        try{
> +                                            Map<String, Object>  
> subVariantMap = dispatcher.runSync("getAllProductVariants",  
> UtilMisc.toMap("productId", assocProduct.get("productIdTo")));
> +                                             
> if(subVariantMap.get("responseMessage").equals("success") &&  
> subVariantMap.get("assocProducts") != null){
> +                                                 
> variantList.addAll((FastList<GenericValue>)  
> subVariantMap.get("assocProducts"));
> +                                            }
> + 
>                                         }catch 
> (GenericServiceException e){
> +                                            Debug.logError(e,  
> "Unable to getAllProductVariants for productId (" +  
> assocProduct.get("productIdTo") +"): ", module);
> +                                        }
> +                                    }
> +                                }catch(GenericServiceException e){
> +                                    Debug.logError(e, "Unable to  
> getProduct for productId (" + assocProduct.get("productIdTo") +"):  
> ", module);
> +                                }
> +                            }
> +                        }
> +                    }catch(GenericServiceException e){
> +                        Debug.logError(e, "Unable to  
> getAllProductVariants for productId (" + productId +"): ", module);
> +                    }
> +                } // Variants
> +
> +                // save (Virtual) Product
> +                variantList.addFirst(product);
> +            }catch(GenericServiceException e){
> +                Debug.logError(e, "Unable to getProduct for  
> productId (" + productId +"): ", module);
> +            }
> +        }
> +
> +        // some default message settings
> +        String errorPrefixStr =  
> UtilProperties.getMessage("DefaultMessages", "service.error.prefix",  
> locale);
> +        String errorSuffixStr =  
> UtilProperties.getMessage("DefaultMessages", "service.error.suffix",  
> locale);
> +        String messagePrefixStr =  
> UtilProperties.getMessage("DefaultMessages",  
> "service.message.prefix", locale);
> +        String messageSuffixStr =  
> UtilProperties.getMessage("DefaultMessages",  
> "service.message.suffix", locale);
> +
> +        // prepare the error message and success message lists
> +        List<Object> errorMessages = FastList.newInstance();
> +        List<String> successMessages = FastList.newInstance();
> +
> +        // Check the global-transaction attribute of the event from  
> the controller to see if the
> +        //  event should be wrapped in a transaction
> +        String requestUri =  
> RequestHandler.getRequestUri(request.getPathInfo());
> +        ConfigXMLReader.ControllerConfig controllerConfig =  
> ConfigXMLReader 
> .getControllerConfig 
> (ConfigXMLReader.getControllerConfigURL(servletContext));
> +        boolean eventGlobalTransaction =  
> controllerConfig 
> .requestMapMap.get(requestUri).event.globalTransaction;
> +
> +        // big try/finally to make sure commit or rollback are run
> +        boolean beganTrans = false;
> +        String returnString = null;
> +        try {
> +
> +            // avoid a global Transaction when the called service  
> is to UPDATE or DELETE data
> +            if (eventGlobalTransaction && ! 
> (serviceName.toLowerCase().contains("update") ||  
> serviceName.toLowerCase().contains("delete"))) {
> +                // start the global transaction
> +                try {
> +                    beganTrans =  
> TransactionUtil.begin(modelService.transactionTimeout *  
> variantList.size());
> +                } catch (GenericTransactionException e) {
> +                    throw new EventHandlerException("Problem  
> starting service-variant global transaction", e);
> +                }
> +            }
> +
> +            // now loop throw the Variant Products and prepare/ 
> invoke the service for each
> +            //for (int i = 0; i < rowCount; i++) {
> +            for(GenericValue variant : variantList){
> +                String currentProductId = new String();
> +
> +                // build the context
> +                Map<String, Object> serviceContext =  
> FastMap.newInstance();
> +                for (ModelParam modelParam:  
> modelService.getInModelParamList()) {
> +                    String paramName = modelParam.name;
> +
> +                    // Debug.logInfo("In ServiceMultiEventHandler  
> processing input parameter [" + modelParam.name +  
> (modelParam.optional?"(optional):":"(required):") + modelParam.mode  
> + "] for service [" + serviceName + "]", module);
> +
> +                    // don't include userLogin, that's taken care  
> of below
> +                    if ("userLogin".equals(paramName)) continue;
> +                    // don't include locale, that is also taken  
> care of below
> +                    if ("locale".equals(paramName)) continue;
> +                    // don't include timeZone, that is also taken  
> care of below
> +                    if ("timeZone".equals(paramName)) continue;
> +
> +                    Object value = null;
> +                    // set Product Id
> +                    if("productId".equals(paramName)){
> +                         
> if(variant.getEntityName().equals("ProductAssoc")){
> +                            value = variant.get("productIdTo");
> +                            currentProductId = (String) value;
> +                        }else{
> +                            value = productId;
> +                            currentProductId = (String) value;
> +                        }
> +                    }else if (modelParam.stringMapPrefix != null &&  
> modelParam.stringMapPrefix.length() > 0) {
> +                        Map<String, Object> paramMap =  
> UtilHttp.makeParamMapWithPrefix(request, modelParam.stringMapPrefix,  
> null /*curSuffix*/);
> +                        value = paramMap;
> +                    } else if (modelParam.stringListSuffix != null  
> && modelParam.stringListSuffix.length() > 0) {
> +                        List<Object> paramList =  
> UtilHttp.makeParamListWithSuffix(request,  
> modelParam.stringListSuffix, null);
> +                        value = paramList;
> +                    } else {
> +                        // check attributes; do this before  
> parameters so that attribute which can be changed by code can  
> override parameters which can't
> +                        value = request.getAttribute(paramName /*+  
> curSuffix*/);
> +
> +                        // first check for request parameters
> +                        if (value == null) {
> +                            String[] paramArr =  
> request.getParameterValues(paramName /*+ curSuffix*/);
> +                            if (paramArr != null) {
> +                                if (paramArr.length > 1) {
> +                                    value = Arrays.asList(paramArr);
> +                                } else {
> +                                    value = paramArr[0];
> +                                }
> +                            }
> +                        }
> +
> +                        // if the parameter wasn't passed and no  
> other value found, check the session
> +                        if (value == null) {
> +                            value = session.getAttribute(paramName / 
> *+ curSuffix*/);
> +                        }
> +
> +                        // now check global scope
> +                        if (value == null) {
> +                            if (checkGlobalScope) {
> +                                String[] gParamArr =  
> request.getParameterValues(paramName);
> +                                if (gParamArr != null) {
> +                                    if (gParamArr.length > 1) {
> +                                        value =  
> Arrays.asList(gParamArr);
> +                                    } else {
> +                                        value = gParamArr[0];
> +                                    }
> +                                }
> +                                if (value == null) {
> +                                    value =  
> request.getAttribute(paramName);
> +                                }
> +                                if (value == null) {
> +                                    value =  
> session.getAttribute(paramName);
> +                                }
> +                            }
> +                        }
> +
> +                        if (value == null) {
> +                            // still null, give up for this one
> +                            continue;
> +                        }
> +
> +                        if (value instanceof String && ((String)  
> value).length() == 0) {
> +                            // interpreting empty fields as null  
> values for each in back end handling...
> +                            value = null;
> +                        }
> +                    }
> +                    // set even if null so that values will get  
> nulled in the db later on
> +                    serviceContext.put(paramName, value);
> +
> +                    // Debug.logInfo("In ServiceMultiEventHandler  
> got value [" + value + "] for input parameter [" + paramName + "]  
> for service [" + serviceName + "]", module);
> +                }
> +
> +                // get only the parameters for this service -  
> converted to proper type
> +                serviceContext =  
> modelService.makeValid(serviceContext, ModelService.IN_PARAM, true,  
> null, timeZone, locale);
> +
> +                // include the UserLogin value object
> +                if (userLogin != null) {
> +                    serviceContext.put("userLogin", userLogin);
> +                }
> +
> +                // include the Locale object
> +                if (locale != null) {
> +                    serviceContext.put("locale", locale);
> +                }
> +
> +                // include the TimeZone object
> +                if (timeZone != null) {
> +                    serviceContext.put("timeZone", timeZone);
> +                }
> +
> +                // Debug.logInfo("ready to call " + serviceName + "  
> with context " + serviceContext, module);
> +
> +                // invoke the service
> +                Map<String, Object> result = null;
> +                try {
> +                    result = dispatcher.runSync(serviceName,  
> serviceContext);
> +                } catch (ServiceAuthException e) {
> +                    // not logging since the service engine already  
> did
> +                    errorMessages.add(messagePrefixStr + "Service  
> invocation error on productId (" + currentProductId +"): " +  
> e.getNonNestedMessage());
> +                } catch (ServiceValidationException e) {
> +                    // not logging since the service engine already  
> did
> +                     
> request.setAttribute("serviceValidationException", e);
> +                    List<String> errors = e.getMessageList();
> +                    if (errors != null) {
> +                        for (String message: errors) {
> +                            errorMessages.add("Service invocation  
> error on productId (" + currentProductId + "): " + message);
> +                        }
> +                    } else {
> +                        errorMessages.add(messagePrefixStr +  
> "Service invocation error on productId (" + currentProductId +"): "  
> + e.getNonNestedMessage());
> +                    }
> +                } catch (GenericServiceException e) {
> +                    Debug.logError(e, "Service invocation error",  
> module);
> +                    errorMessages.add(messagePrefixStr + "Service  
> invocation error on productId (" + currentProductId +"): " +  
> e.getNested() + messageSuffixStr);
> +                }
> +
> +                if (result == null) {
> +                    returnString = ModelService.RESPOND_SUCCESS;
> +                } else {
> +                    // check for an error message
> +                    String errorMessage =  
> ServiceUtil.makeErrorMessage(result, messagePrefixStr,  
> messageSuffixStr, "", "");
> +                    if (UtilValidate.isNotEmpty(errorMessage)) {
> +                        errorMessages.add(errorMessage);
> +                    }
> +
> +                    // get the success messages
> +                    if (! 
> UtilValidate 
> .isEmpty((String)result.get(ModelService.SUCCESS_MESSAGE))) {
> +                        String newSuccessMessage =  
> (String)result.get(ModelService.SUCCESS_MESSAGE);
> +                        if (! 
> successMessages.contains(newSuccessMessage)) {
> +                            successMessages.add(newSuccessMessage);
> +                        }
> +                    }
> +                    if (! 
> UtilValidate 
> .isEmpty((List)result.get(ModelService.SUCCESS_MESSAGE_LIST))) {
> +                        List newSuccessMessages =  
> (List)result.get(ModelService.SUCCESS_MESSAGE_LIST);
> +                        for (int j = 0; j <  
> newSuccessMessages.size(); j++) {
> +                            String newSuccessMessage =  
> (String)newSuccessMessages.get(j);
> +                            if (! 
> successMessages.contains(newSuccessMessage)) {
> +                                 
> successMessages.add(newSuccessMessage);
> +                            }
> +                        }
> +                    }
> +                }
> +                // set the results in the request
> +                if ((result != null) && (result.entrySet() !=  
> null)) {
> +                    for (Map.Entry<String, Object> rme:  
> result.entrySet()) {
> +                        String resultKey = rme.getKey();
> +                        Object resultValue = rme.getValue();
> +
> +                        if (resultKey != null && ! 
> ModelService.RESPONSE_MESSAGE.equals(resultKey) && ! 
> ModelService.ERROR_MESSAGE.equals(resultKey) &&
> +                                ! 
> ModelService.ERROR_MESSAGE_LIST.equals(resultKey) && ! 
> ModelService.ERROR_MESSAGE_MAP.equals(resultKey) &&
> +                                ! 
> ModelService.SUCCESS_MESSAGE.equals(resultKey) && ! 
> ModelService.SUCCESS_MESSAGE_LIST.equals(resultKey)) {
> +                            request.setAttribute(resultKey,  
> resultValue);
> +                        }
> +                    }
> +                }
> +            }
> +        } finally {
> +            if (errorMessages.size() > 0) {
> +                if (eventGlobalTransaction && ! 
> (serviceName.toLowerCase().contains("update") ||  
> serviceName.toLowerCase().contains("delete"))) {
> +                    // rollback the global transaction
> +                    try {
> +                        TransactionUtil.rollback(beganTrans, "Error  
> in service-variant event handling: " + errorMessages.toString(),  
> null);
> +                    } catch (GenericTransactionException e) {
> +                        Debug.logError(e, "Could not rollback  
> service-variant global transaction", module);
> +                    }
> +                }
> +                errorMessages.add(0, errorPrefixStr);
> +                errorMessages.add(errorSuffixStr);
> +                StringBuilder errorBuf = new StringBuilder();
> +                for (Object em: errorMessages) {
> +                    errorBuf.append(em + "\n");
> +                }
> +                request.setAttribute("_ERROR_MESSAGE_",  
> errorBuf.toString());
> +                returnString = "error";
> +            } else {
> +                if (eventGlobalTransaction) {
> +                    // commit the global transaction
> +                    try {
> +                        TransactionUtil.commit(beganTrans);
> +                    } catch (GenericTransactionException e) {
> +                        Debug.logError(e, "Could not commit service- 
> variant global transaction", module);
> +                        throw new EventHandlerException("Commit  
> service-variant global transaction failed");
> +                    }
> +                }
> +                if (successMessages.size() > 0) {
> +                    request.setAttribute("_EVENT_MESSAGE_LIST_",  
> successMessages);
> +                }
> +                returnString = "success";
> +            }
> +        }
> +
> +        return returnString;
> +    }
> +}
>
>


Re: svn commit: r750878 - in /ofbiz/trunk: applications/product/webapp/catalog/WEB-INF/controller.xml applications/product/webapp/catalog/product/ProductForms.xml framework/webapp/src/org/ofbiz/webapp/event/ServiceVariantsEventHandler.java

Posted by Jacques Le Roux <ja...@les7arts.com>.
Oops, sorry reverted at revision: 751001.
It looked a bit weird when I 1st reviewed it, but I finally found it a good idea and forgot the product dependency (actually I 
forgot that I was commiting in framework)
I will explain to Eric in order to find a good solution

Jacques

From: "David E Jones" <jo...@apache.org>
>
> Please revert this patch:
>
> 1. the ServiceVariantEventHandler is in the framework and is dependent  on the applications/product component
>
> 2. creating an event handler for this is pure silliness in the first  place and should simply be done with a custom event
>
> -David
>
>
> On Mar 6, 2009, at 5:41 AM, jleroux@apache.org wrote:
>
>> Author: jleroux
>> Date: Fri Mar  6 12:41:38 2009
>> New Revision: 750878
>>
>> URL: http://svn.apache.org/viewvc?rev=750878&view=rev
>> Log:
>> A modified patch from Eric De Maulde "When a virtual product is  modified, its variants aren't modified" 
>> (https://issues.apache.org/jira/browse/OFBIZ-2228 ) - OFBIZ-2228
>> Also I removed an update link from Product suppliers lists (not  fields were modifiable)
>> More formatting to come (but in all OFBiz, ie no only in  ServiceVariantsEventHandler.java)
>>
>> Added:
>>    ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/event/ ServiceVariantsEventHandler.java
>> Modified:
>>    ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/ controller.xml
>>    ofbiz/trunk/applications/product/webapp/catalog/product/ ProductForms.xml
>>
>> Modified: ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/ controller.xml
>> URL: 
>> http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/controller.xml?rev=750878&r1=750877&r2=750878&view=diff
>> = = = = = = = = ======================================================================
>> --- ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/ controller.xml (original)
>> +++ ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/ controller.xml Fri Mar  6 12:41:38 2009
>> @@ -25,6 +25,7 @@
>>     <owner>Copyright 2001-2008 The Apache Software Foundation</owner>
>>
>>     <handler name="service-multi" type="request"  class="org.ofbiz.webapp.event.ServiceMultiEventHandler"/>
>> +    <handler name="service-variant" type="request"  class="org.ofbiz.webapp.event.ServiceVariantsEventHandler"/>
>>     <handler name="groovy" type="request"  class="org.ofbiz.webapp.event.GroovyEventHandler"/>
>>
>>     <firstvisit></firstvisit>
>> @@ -536,19 +537,19 @@
>>     </request-map>
>>     <request-map uri="createProductPrice">
>>         <security https="true" auth="true"/>
>> -        <event type="service" path="" invoke="createProductPrice"/>
>> +        <event type="service-variant" path=""  invoke="createProductPrice"/>
>>         <response name="success" type="view"  value="EditProductPrices"/>
>>         <response name="error" type="view" value="EditProductPrices"/>
>>     </request-map>
>>     <request-map uri="updateProductPrice">
>>         <security https="true" auth="true"/>
>> -        <event type="service" path="" invoke="updateProductPrice"/>
>> +        <event type="service-variant" path=""  invoke="updateProductPrice"/>
>>         <response name="success" type="view"  value="EditProductPrices"/>
>>         <response name="error" type="view" value="EditProductPrices"/>
>>     </request-map>
>>     <request-map uri="deleteProductPrice">
>>         <security https="true" auth="true"/>
>> -        <event type="service" path="" invoke="deleteProductPrice"/>
>> +        <event type="service-variant" path=""  invoke="deleteProductPrice"/>
>>         <response name="success" type="view"  value="EditProductPrices"/>
>>         <response name="error" type="view" value="EditProductPrices"/>
>>     </request-map>
>> @@ -738,19 +739,19 @@
>>     </request-map>
>>     <request-map uri="addProductToCategory">
>>         <security https="true" auth="true"/>
>> -        <event type="service" path=""  invoke="safeAddProductToCategory"/>
>> +        <event type="service-variant" path=""  invoke="safeAddProductToCategory"/>
>>         <response name="success" type="view"  value="EditProductCategories"/>
>>         <response name="error" type="view"  value="EditProductCategories"/>
>>     </request-map>
>>     <request-map uri="updateProductToCategory">
>>         <security https="true" auth="true"/>
>> -        <event type="service" path=""  invoke="updateProductToCategory"/>
>> +        <event type="service-variant" path=""  invoke="updateProductToCategory"/>
>>         <response name="success" type="view"  value="EditProductCategories"/>
>>         <response name="error" type="view"  value="EditProductCategories"/>
>>     </request-map>
>>     <request-map uri="removeProductFromCategory">
>>         <security https="true" auth="true"/>
>> -        <event type="service" path=""  invoke="removeProductFromCategory"/>
>> +        <event type="service-variant" path=""  invoke="removeProductFromCategory"/>
>>         <response name="success" type="view"  value="EditProductCategories"/>
>>         <response name="error" type="view"  value="EditProductCategories"/>
>>     </request-map>
>> @@ -2273,7 +2274,7 @@
>>     <request-map uri="EditProductSuppliers"><security https="true"  auth="true"/><response name="success" type="view" 
>> value="EditSupplierProduct"/></request-map>
>>     <request-map uri="createSupplierProduct">
>>         <security https="true" auth="true"/>
>> -        <event type="service" path=""  invoke="createSupplierProduct"/>
>> +        <event type="service-variant" path=""  invoke="createSupplierProduct"/>
>>         <response name="success" type="view"  value="EditSupplierProduct"/>
>>         <response name="error" type="view"  value="EditSupplierProduct"/>
>>     </request-map>
>> @@ -2285,7 +2286,7 @@
>>     </request-map>
>>     <request-map uri="removeSupplierProduct">
>>         <security https="true" auth="true"/>
>> -        <event type="service" path=""  invoke="removeSupplierProduct"/>
>> +        <event type="service-variant" path=""  invoke="removeSupplierProduct"/>
>>         <response name="success" type="view"  value="EditSupplierProduct"/>
>>         <response name="error" type="view"  value="EditSupplierProduct"/>
>>     </request-map>
>> @@ -2314,19 +2315,19 @@
>>     <request-map uri="ProductConfigItemArticle"><security  https="true" auth="true"/><response name="success" type="view" 
>> value="ProductConfigItemArticle"/></request-map>
>>     <request-map uri="createProductConfig">
>>         <security https="true" auth="true"/>
>> -        <event type="service" path="" invoke="createProductConfig"/>
>> +        <event type="service-variant" path=""  invoke="createProductConfig"/>
>>         <response name="success" type="view"  value="EditProductConfigs"/>
>>         <response name="error" type="view"  value="EditProductConfigs"/>
>>     </request-map>
>>     <request-map uri="updateProductConfig">
>>         <security https="true" auth="true"/>
>> -        <event type="service" path="" invoke="updateProductConfig"/>
>> +        <event type="service-variant" path=""  invoke="updateProductConfig"/>
>>         <response name="success" type="view"  value="EditProductConfigs"/>
>>         <response name="error" type="view"  value="EditProductConfigs"/>
>>     </request-map>
>>     <request-map uri="deleteProductConfig">
>>         <security https="true" auth="true"/>
>> -        <event type="service" path="" invoke="deleteProductConfig"/>
>> +        <event type="service-variant" path=""  invoke="deleteProductConfig"/>
>>         <response name="success" type="view"  value="EditProductConfigs"/>
>>         <response name="error" type="view"  value="EditProductConfigs"/>
>>     </request-map>
>>
>> Modified: ofbiz/trunk/applications/product/webapp/catalog/product/ ProductForms.xml
>> URL: 
>> http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/webapp/catalog/product/ProductForms.xml?rev=750878&r1=750877&r2=750878&view=diff
>> = = = = = = = = ======================================================================
>> --- ofbiz/trunk/applications/product/webapp/catalog/product/ ProductForms.xml (original)
>> +++ ofbiz/trunk/applications/product/webapp/catalog/product/ ProductForms.xml Fri Mar  6 12:41:38 2009
>> @@ -384,6 +384,12 @@
>>                 </entity-options>
>>             </drop-down>
>>         </field>
>> +        <field name="modifyVariants" title="Modify Variants">
>> +            <drop-down allow-empty="false" no-current-selected- key="N">
>> +                <option key="Y" description="${uiLabelMap.CommonY}"/>
>> +                <option key="N" description="${uiLabelMap.CommonN}"/>
>> +            </drop-down>
>> +        </field>
>>         <field name="submitButton" title="$ {uiLabelMap.CommonCreate}" widget-style="smallSubmit"><submit button- 
>> type="button"/></field>
>>     </form>
>>     <form name="UpdateProductPrice" type="list"  target="updateProductPrice" title="" list-name="productPrices"
>> @@ -471,6 +477,12 @@
>>         <field name="sequenceNum" title="$ {uiLabelMap.ProductSequenceNum}" ></field>
>>         <field name="quantity" title="${uiLabelMap.ProductQuantity}"
>> ></field>
>>         <field name="comments" ><textarea/></field>
>> +        <field name="modifyVariants" title="Modify Variants">
>> +            <drop-down allow-empty="false" no-current-selected- key="N">
>> +                <option key="Y" description="${uiLabelMap.CommonY}"/>
>> +                <option key="N" description="${uiLabelMap.CommonN}"/>
>> +            </drop-down>
>> +        </field>
>>         <field name="submitButton" title="${uiLabelMap.CommonAdd}"  widget-style="smallSubmit"><submit 
>> button-type="button"/></field>
>>     </form>
>>     <form name="UpdateProductCategoryMemeber" type="list"  target="updateProductToCategory" title="" list- 
>> name="productCategoryMembers"
>> @@ -820,6 +832,12 @@
>>                 <option key="N" description="${uiLabelMap.CommonN}"/>
>>             </drop-down>
>>         </field>
>> +        <field name="modifyVariants" title="Modify Variants">
>> +            <drop-down allow-empty="false" no-current-selected- key="N">
>> +                <option key="Y" description="${uiLabelMap.CommonY}"/>
>> +                <option key="N" description="${uiLabelMap.CommonN}"/>
>> +            </drop-down>
>> +        </field>
>>         <field use-when="supplierProduct == null"  name="submitButton" title="${uiLabelMap.CommonCreate}"><submit 
>> button-type="button"/></field>
>>         <field use-when="supplierProduct != null"  name="submitButton" title="${uiLabelMap.CommonUpdate}"><submit 
>> button-type="button"/></field>
>>     </form>
>> @@ -849,10 +867,11 @@
>>             header-link="EditProductSuppliers?productId=$ {productId}&amp;orderBy=lastPrice" header-link-style="buttontext">
>>                 <display type="currency" currency="${currencyUomId}"/>
>>         </field>
>> -        <field name="updateLink" title="$ {uiLabelMap.CommonEmptyHeader}" widget-style="buttontext">
>> +        <!-- not usable : no fields modifiable -->
>> +        <!--field name="updateLink" title="$ {uiLabelMap.CommonEmptyHeader}" widget-style="buttontext">
>>             <hyperlink target="EditProductSuppliers?productId=$ {productId}&amp;partyId=${partyId}&amp;currencyUomId=$ 
>> {currencyUomId}&amp;minimumOrderQuantity=$ {minimumOrderQuantity}&amp;availableFromDate=${availableFromDate}"
>>                 description="${uiLabelMap.CommonUpdate}" also- hidden="false"/>
>> -        </field>
>> +        </field-->
>>         <field name="deleteLink" title="$ {uiLabelMap.CommonEmptyHeader}" widget-style="buttontext">
>>             <hyperlink target="removeSupplierProduct?productId=$ {productId}&amp;partyId=${partyId}&amp;currencyUomId=$ 
>> {currencyUomId}&amp;minimumOrderQuantity=$ {minimumOrderQuantity}&amp;availableFromDate=${availableFromDate}"
>>                 description="${uiLabelMap.CommonDelete}" also- hidden="false"/>
>> @@ -877,6 +896,12 @@
>>                 </entity-options>
>>             </drop-down>
>>         </field>
>> +        <field name="modifyVariants" title="Modify Variants">
>> +            <drop-down allow-empty="false" no-current-selected- key="N">
>> +                <option key="Y" description="${uiLabelMap.CommonY}"/>
>> +                <option key="N" description="${uiLabelMap.CommonN}"/>
>> +            </drop-down>
>> +        </field>
>>         <field name="submitButton" title="$ {uiLabelMap.CommonCreate}" widget-style="smallSubmit"><submit button- 
>> type="button"/></field>
>>     </form>
>>     <form name="UpdateProductConfig" type="list"  target="updateProductConfig" title="" list-name="productConfigs"
>>
>> Added: ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/event/ ServiceVariantsEventHandler.java
>> URL: 
>> http://svn.apache.org/viewvc/ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/event/ServiceVariantsEventHandler.java?rev=750878&view=auto
>> = = = = = = = = ======================================================================
>> --- ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/event/ ServiceVariantsEventHandler.java (added)
>> +++ ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/event/ ServiceVariantsEventHandler.java Fri Mar  6 12:41:38 2009
>> @@ -0,0 +1,433 @@
>> +/ *******************************************************************************
>> + * /Licensed to the Apache Software Foundation (ASF) under one
>> + * or more contributor license agreements.  See the NOTICE file
>> + * distributed with this work for additional information
>> + * regarding copyright ownership.  The ASF licenses this file
>> + * to you under the Apache License, Version 2.0 (the
>> + * "License"); you may not use this file except in compliance
>> + * with the License.  You may obtain a copy of the License at
>> + *
>> + * http://www.apache.org/licenses/LICENSE-2.0
>> + *
>> + * Unless required by applicable law or agreed to in writing,
>> + * software distributed under the License is distributed on an
>> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>> + * KIND, either express or implied.  See the License for the
>> + * specific language governing permissions and limitations
>> + * under the License.
>> +  *******************************************************************************/
>> +package org.ofbiz.webapp.event;
>> +
>> +import java.util.Arrays;
>> +import java.util.List;
>> +import java.util.Locale;
>> +import java.util.Map;
>> +import java.util.TimeZone;
>> +
>> +import javax.servlet.ServletContext;
>> +import javax.servlet.http.HttpServletRequest;
>> +import javax.servlet.http.HttpServletResponse;
>> +import javax.servlet.http.HttpSession;
>> +
>> +import javolution.util.FastList;
>> +import javolution.util.FastMap;
>> +
>> +import org.ofbiz.base.util.Debug;
>> +import org.ofbiz.base.util.UtilHttp;
>> +import org.ofbiz.base.util.UtilMisc;
>> +import org.ofbiz.base.util.UtilProperties;
>> +import org.ofbiz.base.util.UtilValidate;
>> +import org.ofbiz.entity.GenericValue;
>> +import org.ofbiz.entity.transaction.GenericTransactionException;
>> +import org.ofbiz.entity.transaction.TransactionUtil;
>> +import org.ofbiz.service.DispatchContext;
>> +import org.ofbiz.service.GenericServiceException;
>> +import org.ofbiz.service.LocalDispatcher;
>> +import org.ofbiz.service.ModelParam;
>> +import org.ofbiz.service.ModelService;
>> +import org.ofbiz.service.ServiceAuthException;
>> +import org.ofbiz.service.ServiceUtil;
>> +import org.ofbiz.service.ServiceValidationException;
>> +import org.ofbiz.webapp.control.ConfigXMLReader;
>> +import org.ofbiz.webapp.control.RequestHandler;
>> +
>> +/**
>> + * ServiceVariantsEventHandler - Event handler for running a  service multiple times, over all variant related to the virtual 
>> product
>> + */
>> +public class ServiceVariantsEventHandler implements EventHandler {
>> +
>> +    public static final String module =  ServiceVariantsEventHandler.class.getName();
>> +
>> +    public static final String SYNC = "sync";
>> +    public static final String ASYNC = "async";
>> +
>> +    protected ServletContext servletContext;
>> +
>> +    /**
>> +     * @see  org.ofbiz.webapp.event.EventHandler#init(javax.servlet.ServletContext)
>> +     */
>> +    public void init(ServletContext servletContext) throws  EventHandlerException {
>> +        this.servletContext = servletContext;
>> +    }
>> +
>> +    /**
>> +     * @see  org.ofbiz.webapp.event.EventHandler#invoke(java.lang.String,  java.lang.String, 
>> javax.servlet.http.HttpServletRequest,  javax.servlet.http.HttpServletResponse)
>> +     */
>> +    public String invoke(String eventPath, String eventMethod,  HttpServletRequest request, HttpServletResponse response) throws 
>> EventHandlerException {
>> +        // TODO: consider changing this to use the new  UtilHttp.parseMultiFormData method
>> +
>> +        // make sure we have a valid reference to the Service Engine
>> +        LocalDispatcher dispatcher = (LocalDispatcher)  request.getAttribute("dispatcher");
>> +        if (dispatcher == null) {
>> +            throw new EventHandlerException("The local service  dispatcher is null");
>> +        }
>> +        DispatchContext dctx = dispatcher.getDispatchContext();
>> +        if (dctx == null) {
>> +            throw new EventHandlerException("Dispatch context  cannot be found");
>> +        }
>> +
>> +        // get the details for the service(s) to call
>> +        String mode = SYNC;
>> +        String serviceName = null;
>> +
>> +        if (eventPath == null || eventPath.length() == 0) {
>> +            mode = SYNC;
>> +        } else {
>> +            mode = eventPath;
>> +        }
>> +
>> +        // we only support SYNC mode in this handler
>> +        if (!SYNC.equals(mode)) {
>> +            throw new EventHandlerException("Async mode is not  supported");
>> +        }
>> +
>> +        // nake sure we have a defined service to call
>> +        serviceName = eventMethod;
>> +        if (serviceName == null) {
>> +            throw new EventHandlerException("Service name  (eventMethod) cannot be null");
>> +        }
>> +        if (Debug.verboseOn()) Debug.logVerbose("[Set mode/ service]: " + mode + "/" + serviceName, module);
>> +
>> +        // some needed info for when running the service
>> +        Locale locale = UtilHttp.getLocale(request);
>> +        TimeZone timeZone = UtilHttp.getTimeZone(request);
>> +        HttpSession session = request.getSession();
>> +        GenericValue userLogin = (GenericValue)  session.getAttribute("userLogin");
>> +
>> +        // get the service model to generate context(s)
>> +        ModelService modelService = null;
>> +
>> +        try {
>> +            modelService = dctx.getModelService(serviceName);
>> +        } catch (GenericServiceException e) {
>> +            throw new EventHandlerException("Problems getting the  service model", e);
>> +        }
>> +
>> +        if (modelService == null) {
>> +            throw new EventHandlerException("Problems getting the  service model");
>> +        }
>> +
>> +        if (Debug.verboseOn()) Debug.logVerbose("[Processing]:  SERVICE Event", module);
>> +        if (Debug.verboseOn()) Debug.logVerbose("[Using delegator]:  " + dispatcher.getDelegator().getDelegatorName(), module);
>> +
>> +        // check if we are to also look in a global scope (no  delimiter)
>> +        boolean checkGlobalScope =  request.getParameter("_checkGlobalScope") == null ? true :
>> + !"N ".equalsIgnoreCase(request.getParameter("_checkGlobalScope"));
>> +
>> +        // get All Variant Products related to the Virtual Product
>> +        String productId = new String();
>> +        FastList<GenericValue> variantList = FastList.newInstance();
>> +         if(UtilValidate.isNotEmpty(request.getParameter("productId"))) {
>> +            productId = request.getParameter("productId");
>> +            // check Virtual Current Product
>> +            try{
>> +                GenericValue product = (GenericValue)  dispatcher.runSync("getProduct", UtilMisc.toMap("productId", 
>> productId)).get("product");
>> +
>> +                // check if we have to implement changes to all  Product Variants
>> +                if(! request.getParameterMap().containsKey("modifyVariants")
>> +                   ||  request.getParameterMap().containsKey("modifyVariants")
>> +                   &&  request.getParameter("modifyVariants").equals("Y")
>> +                   &&  product.get("isVirtual").toString().equals("Y")) {
>> +                    // save Variant Products
>> +                    try {
>> +                        Map<String, Object> variantMap =  dispatcher.runSync("getAllProductVariants", 
>> UtilMisc.toMap("productId", productId));
>> +                        if  (variantMap.get("responseMessage").equals("success") &&  variantMap.get("assocProducts") != null) {
>> +                            FastList<GenericValue>  assocProductsList = (FastList<GenericValue>) 
>> variantMap.get("assocProducts");
>> +                            variantList.addAll(assocProductsList);
>> +
>> +                            // get Sub-Variant
>> +                            for(GenericValue assocProduct:  assocProductsList){
>> +                                try{
>> +                                    GenericValue variant =  (GenericValue) dispatcher.runSync("getProduct", 
>> UtilMisc.toMap("productId",  assocProduct.get("productIdTo"))).get("product");
>> +                                     if(variant.get("isVirtual").toString().equals("Y")){
>> +                                        // save Sub-Variant Products
>> +                                        try{
>> +                                            Map<String, Object>  subVariantMap = dispatcher.runSync("getAllProductVariants", 
>> UtilMisc.toMap("productId", assocProduct.get("productIdTo")));
>> +                                             if(subVariantMap.get("responseMessage").equals("success") && 
>> subVariantMap.get("assocProducts") != null){
>> +                                                 variantList.addAll((FastList<GenericValue>) 
>> subVariantMap.get("assocProducts"));
>> +                                            }
>> + }catch (GenericServiceException e){
>> +                                            Debug.logError(e,  "Unable to getAllProductVariants for productId (" + 
>> assocProduct.get("productIdTo") +"): ", module);
>> +                                        }
>> +                                    }
>> +                                }catch(GenericServiceException e){
>> +                                    Debug.logError(e, "Unable to  getProduct for productId (" + assocProduct.get("productIdTo") 
>> +"):  ", module);
>> +                                }
>> +                            }
>> +                        }
>> +                    }catch(GenericServiceException e){
>> +                        Debug.logError(e, "Unable to  getAllProductVariants for productId (" + productId +"): ", module);
>> +                    }
>> +                } // Variants
>> +
>> +                // save (Virtual) Product
>> +                variantList.addFirst(product);
>> +            }catch(GenericServiceException e){
>> +                Debug.logError(e, "Unable to getProduct for  productId (" + productId +"): ", module);
>> +            }
>> +        }
>> +
>> +        // some default message settings
>> +        String errorPrefixStr =  UtilProperties.getMessage("DefaultMessages", "service.error.prefix",  locale);
>> +        String errorSuffixStr =  UtilProperties.getMessage("DefaultMessages", "service.error.suffix",  locale);
>> +        String messagePrefixStr =  UtilProperties.getMessage("DefaultMessages",  "service.message.prefix", locale);
>> +        String messageSuffixStr =  UtilProperties.getMessage("DefaultMessages",  "service.message.suffix", locale);
>> +
>> +        // prepare the error message and success message lists
>> +        List<Object> errorMessages = FastList.newInstance();
>> +        List<String> successMessages = FastList.newInstance();
>> +
>> +        // Check the global-transaction attribute of the event from  the controller to see if the
>> +        //  event should be wrapped in a transaction
>> +        String requestUri =  RequestHandler.getRequestUri(request.getPathInfo());
>> +        ConfigXMLReader.ControllerConfig controllerConfig =  ConfigXMLReader .getControllerConfig 
>> (ConfigXMLReader.getControllerConfigURL(servletContext));
>> +        boolean eventGlobalTransaction =  controllerConfig .requestMapMap.get(requestUri).event.globalTransaction;
>> +
>> +        // big try/finally to make sure commit or rollback are run
>> +        boolean beganTrans = false;
>> +        String returnString = null;
>> +        try {
>> +
>> +            // avoid a global Transaction when the called service  is to UPDATE or DELETE data
>> +            if (eventGlobalTransaction && ! (serviceName.toLowerCase().contains("update") || 
>> serviceName.toLowerCase().contains("delete"))) {
>> +                // start the global transaction
>> +                try {
>> +                    beganTrans =  TransactionUtil.begin(modelService.transactionTimeout *  variantList.size());
>> +                } catch (GenericTransactionException e) {
>> +                    throw new EventHandlerException("Problem  starting service-variant global transaction", e);
>> +                }
>> +            }
>> +
>> +            // now loop throw the Variant Products and prepare/ invoke the service for each
>> +            //for (int i = 0; i < rowCount; i++) {
>> +            for(GenericValue variant : variantList){
>> +                String currentProductId = new String();
>> +
>> +                // build the context
>> +                Map<String, Object> serviceContext =  FastMap.newInstance();
>> +                for (ModelParam modelParam:  modelService.getInModelParamList()) {
>> +                    String paramName = modelParam.name;
>> +
>> +                    // Debug.logInfo("In ServiceMultiEventHandler  processing input parameter [" + modelParam.name + 
>> (modelParam.optional?"(optional):":"(required):") + modelParam.mode  + "] for service [" + serviceName + "]", module);
>> +
>> +                    // don't include userLogin, that's taken care  of below
>> +                    if ("userLogin".equals(paramName)) continue;
>> +                    // don't include locale, that is also taken  care of below
>> +                    if ("locale".equals(paramName)) continue;
>> +                    // don't include timeZone, that is also taken  care of below
>> +                    if ("timeZone".equals(paramName)) continue;
>> +
>> +                    Object value = null;
>> +                    // set Product Id
>> +                    if("productId".equals(paramName)){
>> +                         if(variant.getEntityName().equals("ProductAssoc")){
>> +                            value = variant.get("productIdTo");
>> +                            currentProductId = (String) value;
>> +                        }else{
>> +                            value = productId;
>> +                            currentProductId = (String) value;
>> +                        }
>> +                    }else if (modelParam.stringMapPrefix != null &&  modelParam.stringMapPrefix.length() > 0) {
>> +                        Map<String, Object> paramMap =  UtilHttp.makeParamMapWithPrefix(request, modelParam.stringMapPrefix, 
>> null /*curSuffix*/);
>> +                        value = paramMap;
>> +                    } else if (modelParam.stringListSuffix != null  && modelParam.stringListSuffix.length() > 0) {
>> +                        List<Object> paramList =  UtilHttp.makeParamListWithSuffix(request,  modelParam.stringListSuffix, null);
>> +                        value = paramList;
>> +                    } else {
>> +                        // check attributes; do this before  parameters so that attribute which can be changed by code can 
>> override parameters which can't
>> +                        value = request.getAttribute(paramName /*+  curSuffix*/);
>> +
>> +                        // first check for request parameters
>> +                        if (value == null) {
>> +                            String[] paramArr =  request.getParameterValues(paramName /*+ curSuffix*/);
>> +                            if (paramArr != null) {
>> +                                if (paramArr.length > 1) {
>> +                                    value = Arrays.asList(paramArr);
>> +                                } else {
>> +                                    value = paramArr[0];
>> +                                }
>> +                            }
>> +                        }
>> +
>> +                        // if the parameter wasn't passed and no  other value found, check the session
>> +                        if (value == null) {
>> +                            value = session.getAttribute(paramName / *+ curSuffix*/);
>> +                        }
>> +
>> +                        // now check global scope
>> +                        if (value == null) {
>> +                            if (checkGlobalScope) {
>> +                                String[] gParamArr =  request.getParameterValues(paramName);
>> +                                if (gParamArr != null) {
>> +                                    if (gParamArr.length > 1) {
>> +                                        value =  Arrays.asList(gParamArr);
>> +                                    } else {
>> +                                        value = gParamArr[0];
>> +                                    }
>> +                                }
>> +                                if (value == null) {
>> +                                    value =  request.getAttribute(paramName);
>> +                                }
>> +                                if (value == null) {
>> +                                    value =  session.getAttribute(paramName);
>> +                                }
>> +                            }
>> +                        }
>> +
>> +                        if (value == null) {
>> +                            // still null, give up for this one
>> +                            continue;
>> +                        }
>> +
>> +                        if (value instanceof String && ((String)  value).length() == 0) {
>> +                            // interpreting empty fields as null  values for each in back end handling...
>> +                            value = null;
>> +                        }
>> +                    }
>> +                    // set even if null so that values will get  nulled in the db later on
>> +                    serviceContext.put(paramName, value);
>> +
>> +                    // Debug.logInfo("In ServiceMultiEventHandler  got value [" + value + "] for input parameter [" + paramName 
>> + "]  for service [" + serviceName + "]", module);
>> +                }
>> +
>> +                // get only the parameters for this service -  converted to proper type
>> +                serviceContext =  modelService.makeValid(serviceContext, ModelService.IN_PARAM, true,  null, timeZone, locale);
>> +
>> +                // include the UserLogin value object
>> +                if (userLogin != null) {
>> +                    serviceContext.put("userLogin", userLogin);
>> +                }
>> +
>> +                // include the Locale object
>> +                if (locale != null) {
>> +                    serviceContext.put("locale", locale);
>> +                }
>> +
>> +                // include the TimeZone object
>> +                if (timeZone != null) {
>> +                    serviceContext.put("timeZone", timeZone);
>> +                }
>> +
>> +                // Debug.logInfo("ready to call " + serviceName + "  with context " + serviceContext, module);
>> +
>> +                // invoke the service
>> +                Map<String, Object> result = null;
>> +                try {
>> +                    result = dispatcher.runSync(serviceName,  serviceContext);
>> +                } catch (ServiceAuthException e) {
>> +                    // not logging since the service engine already  did
>> +                    errorMessages.add(messagePrefixStr + "Service  invocation error on productId (" + currentProductId +"): " + 
>> e.getNonNestedMessage());
>> +                } catch (ServiceValidationException e) {
>> +                    // not logging since the service engine already  did
>> +                     request.setAttribute("serviceValidationException", e);
>> +                    List<String> errors = e.getMessageList();
>> +                    if (errors != null) {
>> +                        for (String message: errors) {
>> +                            errorMessages.add("Service invocation  error on productId (" + currentProductId + "): " + message);
>> +                        }
>> +                    } else {
>> +                        errorMessages.add(messagePrefixStr +  "Service invocation error on productId (" + currentProductId +"): 
>> "  + e.getNonNestedMessage());
>> +                    }
>> +                } catch (GenericServiceException e) {
>> +                    Debug.logError(e, "Service invocation error",  module);
>> +                    errorMessages.add(messagePrefixStr + "Service  invocation error on productId (" + currentProductId +"): " + 
>> e.getNested() + messageSuffixStr);
>> +                }
>> +
>> +                if (result == null) {
>> +                    returnString = ModelService.RESPOND_SUCCESS;
>> +                } else {
>> +                    // check for an error message
>> +                    String errorMessage =  ServiceUtil.makeErrorMessage(result, messagePrefixStr,  messageSuffixStr, "", "");
>> +                    if (UtilValidate.isNotEmpty(errorMessage)) {
>> +                        errorMessages.add(errorMessage);
>> +                    }
>> +
>> +                    // get the success messages
>> +                    if (! UtilValidate .isEmpty((String)result.get(ModelService.SUCCESS_MESSAGE))) {
>> +                        String newSuccessMessage =  (String)result.get(ModelService.SUCCESS_MESSAGE);
>> +                        if (! successMessages.contains(newSuccessMessage)) {
>> +                            successMessages.add(newSuccessMessage);
>> +                        }
>> +                    }
>> +                    if (! UtilValidate .isEmpty((List)result.get(ModelService.SUCCESS_MESSAGE_LIST))) {
>> +                        List newSuccessMessages =  (List)result.get(ModelService.SUCCESS_MESSAGE_LIST);
>> +                        for (int j = 0; j <  newSuccessMessages.size(); j++) {
>> +                            String newSuccessMessage =  (String)newSuccessMessages.get(j);
>> +                            if (! successMessages.contains(newSuccessMessage)) {
>> +                                 successMessages.add(newSuccessMessage);
>> +                            }
>> +                        }
>> +                    }
>> +                }
>> +                // set the results in the request
>> +                if ((result != null) && (result.entrySet() !=  null)) {
>> +                    for (Map.Entry<String, Object> rme:  result.entrySet()) {
>> +                        String resultKey = rme.getKey();
>> +                        Object resultValue = rme.getValue();
>> +
>> +                        if (resultKey != null && ! ModelService.RESPONSE_MESSAGE.equals(resultKey) && ! 
>> ModelService.ERROR_MESSAGE.equals(resultKey) &&
>> +                                ! ModelService.ERROR_MESSAGE_LIST.equals(resultKey) && ! 
>> ModelService.ERROR_MESSAGE_MAP.equals(resultKey) &&
>> +                                ! ModelService.SUCCESS_MESSAGE.equals(resultKey) && ! 
>> ModelService.SUCCESS_MESSAGE_LIST.equals(resultKey)) {
>> +                            request.setAttribute(resultKey,  resultValue);
>> +                        }
>> +                    }
>> +                }
>> +            }
>> +        } finally {
>> +            if (errorMessages.size() > 0) {
>> +                if (eventGlobalTransaction && ! (serviceName.toLowerCase().contains("update") || 
>> serviceName.toLowerCase().contains("delete"))) {
>> +                    // rollback the global transaction
>> +                    try {
>> +                        TransactionUtil.rollback(beganTrans, "Error  in service-variant event handling: " + 
>> errorMessages.toString(),  null);
>> +                    } catch (GenericTransactionException e) {
>> +                        Debug.logError(e, "Could not rollback  service-variant global transaction", module);
>> +                    }
>> +                }
>> +                errorMessages.add(0, errorPrefixStr);
>> +                errorMessages.add(errorSuffixStr);
>> +                StringBuilder errorBuf = new StringBuilder();
>> +                for (Object em: errorMessages) {
>> +                    errorBuf.append(em + "\n");
>> +                }
>> +                request.setAttribute("_ERROR_MESSAGE_",  errorBuf.toString());
>> +                returnString = "error";
>> +            } else {
>> +                if (eventGlobalTransaction) {
>> +                    // commit the global transaction
>> +                    try {
>> +                        TransactionUtil.commit(beganTrans);
>> +                    } catch (GenericTransactionException e) {
>> +                        Debug.logError(e, "Could not commit service- variant global transaction", module);
>> +                        throw new EventHandlerException("Commit  service-variant global transaction failed");
>> +                    }
>> +                }
>> +                if (successMessages.size() > 0) {
>> +                    request.setAttribute("_EVENT_MESSAGE_LIST_",  successMessages);
>> +                }
>> +                returnString = "success";
>> +            }
>> +        }
>> +
>> +        return returnString;
>> +    }
>> +}
>>
>>
>