svn commit: r562856 - in /ofbiz/trunk/applications/product: data/ProductTypeData.xml src/org/ofbiz/product/product/ProductSearchEvents.java src/org/ofbiz/product/product/ProductsExportToGoogle.java webapp/catalog/find/ExportForms.xml

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

svn commit: r562856 - in /ofbiz/trunk/applications/product: data/ProductTypeData.xml src/org/ofbiz/product/product/ProductSearchEvents.java src/org/ofbiz/product/product/ProductsExportToGoogle.java webapp/catalog/find/ExportForms.xml

jacopoc
Author: jacopoc
Date: Sun Aug  5 05:28:09 2007
New Revision: 562856

URL: http://svn.apache.org/viewvc?view=rev&rev=562856
Log:
Misc improvements to the Google export:
- improved error handling
- google feed id is now stored in GoodIdentification
- fixed and improved delete and update actions

Modified:
    ofbiz/trunk/applications/product/data/ProductTypeData.xml
    ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductSearchEvents.java
    ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductsExportToGoogle.java
    ofbiz/trunk/applications/product/webapp/catalog/find/ExportForms.xml

Modified: ofbiz/trunk/applications/product/data/ProductTypeData.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/data/ProductTypeData.xml?view=diff&rev=562856&r1=562855&r2=562856
==============================================================================
--- ofbiz/trunk/applications/product/data/ProductTypeData.xml (original)
+++ ofbiz/trunk/applications/product/data/ProductTypeData.xml Sun Aug  5 05:28:09 2007
@@ -138,6 +138,7 @@
     <GoodIdentificationType description="SKU" goodIdentificationTypeId="SKU" hasTable="N" parentTypeId=""/>
     <GoodIdentificationType description="UPCA" goodIdentificationTypeId="UPCA" hasTable="N" parentTypeId=""/>
     <GoodIdentificationType description="UPCE" goodIdentificationTypeId="UPCE" hasTable="N" parentTypeId=""/>
+    <GoodIdentificationType description="Google Id" goodIdentificationTypeId="GOOGLE_ID" hasTable="N" parentTypeId=""/>
 
     <InventoryItemType description="Serialized" hasTable="N" inventoryItemTypeId="SERIALIZED_INV_ITEM" parentTypeId=""/>
     <InventoryItemType description="Non-Serialized" hasTable="N" inventoryItemTypeId="NON_SERIAL_INV_ITEM" parentTypeId=""/>

Modified: ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductSearchEvents.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductSearchEvents.java?view=diff&rev=562856&r1=562855&r2=562856
==============================================================================
--- ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductSearchEvents.java (original)
+++ ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductSearchEvents.java Sun Aug  5 05:28:09 2007
@@ -47,6 +47,7 @@
 import org.ofbiz.product.product.ProductSearch.ResultSortOrder;
 import org.ofbiz.service.GenericServiceException;
 import org.ofbiz.service.LocalDispatcher;
+import org.ofbiz.service.ModelService;
 import org.ofbiz.service.ServiceUtil;
 
 /**
@@ -480,7 +481,11 @@
                     }
                     eli.close();
                 } else {
-                    productExportList = UtilMisc.toList(selectResult);
+                    if (selectResult.startsWith("[")) {
+                        productExportList = StringUtil.toList(selectResult);
+                    } else {
+                        productExportList.add(selectResult);
+                    }
                 }
                 String webSiteUrl = (String) request.getParameter("webSiteUrl");
                 String imageUrl = (String) request.getParameter("imageUrl");
@@ -501,12 +506,22 @@
                     inMap.put("userLogin", userLogin);
                     Map exportResult = dispatcher.runSync("exportToGoogle", inMap);
                     if (ServiceUtil.isError(exportResult)) {
-                        errMsg = ServiceUtil.getErrorMessage(exportResult);
-                        Debug.logError(errMsg, module);
-                        request.setAttribute("_ERROR_MESSAGE_", errMsg);
+                        List errorMessages = (List)exportResult.get(ModelService.ERROR_MESSAGE_LIST);
+                        if (UtilValidate.isNotEmpty(errorMessages)) {
+                            request.setAttribute("_ERROR_MESSAGE_LIST_", errorMessages);
+                        } else {
+                            request.setAttribute("_ERROR_MESSAGE_", ServiceUtil.getErrorMessage(exportResult));
+                        }
                         return "error";
+                    } else if (ServiceUtil.isFailure(exportResult)) {
+                        List eventMessages = (List)exportResult.get(ModelService.ERROR_MESSAGE_LIST);
+                        if (UtilValidate.isNotEmpty(eventMessages)) {
+                            request.setAttribute("_EVENT_MESSAGE_LIST_", eventMessages);
+                        } else {
+                            request.setAttribute("_EVENT_MESSAGE_", ServiceUtil.getErrorMessage(exportResult));
+                        }
                     } else {
-                        request.setAttribute("_SUCCESS_MESSAGE_", exportResult.get("successMessage"));
+                        request.setAttribute("_EVENT_MESSAGE_", exportResult.get("successMessage"));
                     }
                 } catch (GenericServiceException e) {
                     errMsg = UtilProperties.getMessage(resource, "productsearchevents.exceptionCallingExportToGoogle", locale);

Modified: ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductsExportToGoogle.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductsExportToGoogle.java?view=diff&rev=562856&r1=562855&r2=562856
==============================================================================
--- ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductsExportToGoogle.java (original)
+++ ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductsExportToGoogle.java Sun Aug  5 05:28:09 2007
@@ -32,6 +32,7 @@
 import java.util.Map;
 import java.util.StringTokenizer;
 
+import javolution.util.FastList;
 import javolution.util.FastMap;
 
 import org.ofbiz.base.util.Debug;
@@ -41,12 +42,15 @@
 import org.ofbiz.base.util.UtilValidate;
 import org.ofbiz.base.util.UtilXml;
 import org.ofbiz.entity.GenericDelegator;
+import org.ofbiz.entity.GenericEntityException;
 import org.ofbiz.entity.GenericValue;
 import org.ofbiz.entity.condition.EntityExpr;
 import org.ofbiz.entity.condition.EntityOperator;
 import org.ofbiz.service.DispatchContext;
 import org.ofbiz.service.LocalDispatcher;
+import org.ofbiz.service.ModelService;
 import org.ofbiz.service.ServiceUtil;
+
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
@@ -57,6 +61,10 @@
 
     public static Map exportToGoogle(DispatchContext dctx, Map context) {
         Locale locale = (Locale) context.get("locale");
+        GenericDelegator delegator = dctx.getDelegator();
+        LocalDispatcher dispatcher = dctx.getDispatcher();
+        
+        Map result = null;
         try {
             String configString = "productsExport.properties";
                             
@@ -77,15 +85,11 @@
         
             StringBuffer dataItemsXml = new StringBuffer();
             
-            Map result = buildDataItemsXml(dctx, context, dataItemsXml);
-            if (!ServiceUtil.isFailure(result)) {
+            result = buildDataItemsXml(dctx, context, dataItemsXml);
+            if (!ServiceUtil.isFailure(result)) {
                 String token = authenticate(authenticationUrl, accountEmail, accountPassword);
                 if (token != null) {    
-                    result = postItem(token, postItemsUrl, developerKey, dataItemsXml, locale, (String)context.get("testMode"));
-                    String msg = ServiceUtil.getErrorMessage(result);
-                    if (msg != null && msg.length() > 0) {
-                        return ServiceUtil.returnFailure(msg);
-                    }
+                    result = postItem(token, postItemsUrl, developerKey, dataItemsXml, locale, (String)context.get("testMode"), (List)result.get("newProductsInGoogle"), (List)result.get("productsRemovedFromGoogle"), dispatcher, delegator);
                 } else {
                     Debug.logError("Error during authentication to Google Account", module);
                     return ServiceUtil.returnFailure(UtilProperties.getMessage(resource, "productsExportToGoogle.errorDuringAuthenticationToGoogle", locale));
@@ -97,7 +101,7 @@
             Debug.logError("Exception in exportToGoogle", module);
             return ServiceUtil.returnFailure(UtilProperties.getMessage(resource, "productsExportToGoogle.exceptionInExportToGoogle", locale));
         }
-        return ServiceUtil.returnSuccess(UtilProperties.getMessage(resource, "productsExportToGoogle.productItemsSentCorrecltyToGoogle", locale));
+        return result;
     }
   
     private static String authenticate(String authenticationUrl, String accountEmail, String accountPassword) {
@@ -173,7 +177,7 @@
     
     private static String toString(InputStream inputStream) throws IOException {
         String string;
-        StringBuilder outputBuilder = new StringBuilder();
+        StringBuffer outputBuilder = new StringBuffer();
         if (inputStream != null) {
             BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
             while (null != (string = reader.readLine())) {
@@ -184,7 +188,7 @@
     }
     
     private static Map postItem(String token, String postItemsUrl, String developerKey, StringBuffer dataItems,
-                                Locale locale, String testMode) throws IOException {
+                                Locale locale, String testMode, List newProductsInGoogle, List productsRemovedFromGoogle, LocalDispatcher dispatcher, GenericDelegator delegator) throws IOException {
         if (Debug.verboseOn()) {
             Debug.logVerbose("Request To Google Base :\n" + dataItems.toString(), module);
         }
@@ -215,10 +219,10 @@
             inputStream = connection.getInputStream();
             response = toString(inputStream);
             if (response != null && response.length() > 0) {
-                result = readResponseFromGoogle(response, locale);
-                String msg = ServiceUtil.getErrorMessage(result);
-                if (msg != null && msg.length() > 0) {
-                    result = ServiceUtil.returnFailure(msg);
+                result = readResponseFromGoogle(response, newProductsInGoogle, productsRemovedFromGoogle, dispatcher, delegator, locale);
+                //String msg = ServiceUtil.getErrorMessage(result);
+                if (ServiceUtil.isError(result)) {
+                    result = ServiceUtil.returnFailure((List)result.get(ModelService.ERROR_MESSAGE_LIST));
                 } else {
                     result = ServiceUtil.returnSuccess();
                 }
@@ -237,6 +241,8 @@
     
     private static Map buildDataItemsXml(DispatchContext dctx, Map context, StringBuffer dataItemsXml) {
         Locale locale = (Locale)context.get("locale");
+        List newProductsInGoogle = FastList.newInstance();
+        List productsRemovedFromGoogle = FastList.newInstance();
         try {
              GenericDelegator delegator = dctx.getDelegator();
              LocalDispatcher dispatcher = dctx.getDispatcher();
@@ -247,6 +253,12 @@
              String statusId = (String)context.get("statusId");
              String trackingCodeId = (String)context.get("trackingCodeId");
             
+             if (!webSiteUrl.startsWith("http://") && !webSiteUrl.startsWith("https://")) {
+                 webSiteUrl = "http://" + webSiteUrl;
+             }
+             if (webSiteUrl.endsWith("/")) {
+                 webSiteUrl = webSiteUrl.substring(0, webSiteUrl.length() - 1);
+             }
              // Get the list of products to be exported to Google Base
              List productsList  = delegator.findByCondition("Product", new EntityExpr("productId", EntityOperator.IN, selectResult), null, null);
             
@@ -267,25 +279,47 @@
                 
                  // Iterate the product list getting all the relevant data
                  Iterator productsListItr = productsList.iterator();
+                 int index = 0;
+                 String itemActionType = null;
                  while(productsListItr.hasNext()) {
+                     itemActionType = actionType;
                      GenericValue prod = (GenericValue)productsListItr.next();
                      String price = getProductPrice(dispatcher, prod);
                      if (price == null) {
                          Debug.logInfo("Price not found for product [" + prod.getString("productId")+ "]; product will not be exported.", module);
                          continue;
                      }
-                     String link = webSiteUrl + "/control/product/~product_id=" + prod.getString("productId") + trackingCodeId;
+                     // TODO: improve this (i.e. get the relative path from the properies file)
+                     String link = webSiteUrl + "/ecommerce/control/product/~product_id=" + prod.getString("productId") + trackingCodeId;
                      String title = UtilFormatOut.encodeXmlValue(prod.getString("productName"));
                      String description = UtilFormatOut.encodeXmlValue(prod.getString("description"));
-                     String image_link = "";
+                     String imageLink = "";
                      if (UtilValidate.isNotEmpty(prod.getString("largeImageUrl"))) {
-                         image_link = imageUrl + prod.getString("largeImageUrl");
+                         imageLink = webSiteUrl + prod.getString("largeImageUrl");
+                     } else if (UtilValidate.isNotEmpty(prod.getString("mediumImageUrl"))) {
+                         imageLink = webSiteUrl + prod.getString("mediumImageUrl");
+                     } else if (UtilValidate.isNotEmpty(prod.getString("smallImageUrl"))) {
+                         imageLink = webSiteUrl + prod.getString("smallImageUrl");
+                     }
+
+                     String googleProductId = null;
+                     if (!"insert".equals(actionType)) {
+                         try {
+                             GenericValue googleProduct = delegator.findByPrimaryKey("GoodIdentification", UtilMisc.toMap("productId", prod.getString("productId"), "goodIdentificationTypeId", "GOOGLE_ID"));
+                             if (UtilValidate.isNotEmpty(googleProduct)) {
+                                googleProductId = googleProduct.getString("idValue");
+                             }
+                         } catch(GenericEntityException gee) {
+                             Debug.logError("Unable to get the Google id for product [" + prod.getString("productId") + "]: " + gee.getMessage(), module);
+                         }
+                     }
+                     if ("update".equals(actionType) && UtilValidate.isEmpty(googleProductId)) {
+                         itemActionType = "insert";
                      }
-                    
                      Element entryElem = UtilXml.addChildElement(feedElem, "entry", feedDocument);
                      Element batchElem = UtilXml.addChildElement(entryElem, "batch:operation", feedDocument);
-                     batchElem.setAttribute("type", actionType);
-                    
+                     batchElem.setAttribute("type", itemActionType);
+
                      // status is draft or deactivate
                      if (statusId != null && ("draft".equals(statusId) || "deactivate".equals(statusId))) {
                          Element appControlElem = UtilXml.addChildElement(entryElem, "app:control", feedDocument);
@@ -303,8 +337,12 @@
                      Element contentElem = UtilXml.addChildElementValue(entryElem, "content", description, feedDocument);
                      contentElem.setAttribute("type", "xhtml");
                     
-                     UtilXml.addChildElementValue(entryElem, "id", link, feedDocument);
-                    
+                     if (UtilValidate.isNotEmpty(googleProductId)) {
+                         UtilXml.addChildElementValue(entryElem, "id", googleProductId, feedDocument);
+                     } else {
+                         UtilXml.addChildElementValue(entryElem, "id", link, feedDocument);
+                     }
+
                      Element linkElem = UtilXml.addChildElement(entryElem, "link", feedDocument);
                      linkElem.setAttribute("rel", "alternate");
                      linkElem.setAttribute("type", "text/html");
@@ -314,9 +352,21 @@
                      UtilXml.addChildElementValue(entryElem, "g:price", price, feedDocument);
                     
                      // if the product has an image it will be published on Google Product Search
-                     if (UtilValidate.isNotEmpty(image_link)) {
-                         UtilXml.addChildElementValue(entryElem, "g:image_link", image_link, feedDocument);
+                     if (UtilValidate.isNotEmpty(imageLink)) {
+                         UtilXml.addChildElementValue(entryElem, "g:image_link", imageLink, feedDocument);
+                     }
+                     // if the product is exported to google for the first time, we add it to the list
+                     if ("insert".equals(itemActionType)) {
+                         newProductsInGoogle.add(prod.getString("productId"));
+                         productsRemovedFromGoogle.add(null);
+                     } else if ("delete".equals(itemActionType)) {
+                         newProductsInGoogle.add(null);
+                         productsRemovedFromGoogle.add(prod.getString("productId"));
+                     } else {
+                         newProductsInGoogle.add(null);
+                         productsRemovedFromGoogle.add(null);
                      }
+                     index++;
                  }
                 
                  dataItemsXml.append(UtilXml.writeXmlDocument(feedDocument));
@@ -327,8 +377,11 @@
          } catch (Exception e) {
             Debug.logError("Exception during building data items to Google", module);
             return ServiceUtil.returnFailure(UtilProperties.getMessage(resource, "productsExportToGoogle.exceptionDuringBuildingDataItemsToGoogle", locale));
-         }
-         return ServiceUtil.returnSuccess();
+         }
+         Map result = ServiceUtil.returnSuccess();
+         result.put("newProductsInGoogle", newProductsInGoogle);
+         result.put("productsRemovedFromGoogle", productsRemovedFromGoogle);
+         return result;
     }
 
     private static String getProductPrice(LocalDispatcher dispatcher, GenericValue product) {
@@ -346,32 +399,59 @@
         return priceString;
     }
     
-    private static Map readResponseFromGoogle(String msg, Locale locale) {
-        StringBuffer message = new StringBuffer();
+    private static Map readResponseFromGoogle(String msg, List newProductsInGoogle, List productsRemovedFromGoogle, LocalDispatcher dispatcher, GenericDelegator delegator, Locale locale) {
+        List message = FastList.newInstance();
         try {
             Document docResponse = UtilXml.readXmlDocument(msg, true);
             Element elemResponse = docResponse.getDocumentElement();
             List atomEntryList = UtilXml.childElementList(elemResponse, "atom:entry");
             Iterator atomEntryElemIter = atomEntryList.iterator();
+            int index = 0;
             while (atomEntryElemIter.hasNext()) {
                 Element atomEntryElement = (Element)atomEntryElemIter.next();
-                List batchInterruptedEntryList = UtilXml.childElementList(atomEntryElement, "batch:interrupted");
-                Iterator batchInterruptedEntryElemIter = batchInterruptedEntryList.iterator();
-                while (batchInterruptedEntryElemIter.hasNext()) {
-                    Element batchInterruptedEntryElement = (Element)batchInterruptedEntryElemIter.next();
-                    String reason = batchInterruptedEntryElement.getAttribute("reason");
-                    message.append(reason);
+                String id = UtilXml.childElementValue(atomEntryElement, "atom:id", "");
+                if (UtilValidate.isNotEmpty(id) && newProductsInGoogle.get(index) != null) {
+                    String productId = (String)newProductsInGoogle.get(index);
+                    try {
+                        GenericValue googleProductId = delegator.makeValue("GoodIdentification", null);
+                        googleProductId.set("goodIdentificationTypeId", "GOOGLE_ID");
+                        googleProductId.set("productId", productId);
+                        googleProductId.set("idValue", id);
+                        delegator.createOrStore(googleProductId);
+                    } catch (GenericEntityException gee) {
+                        Debug.logError("Unable to create or update Google id for product [" + productId + "]: " + gee.getMessage(), module);
+                    }
+                }
+                if (UtilValidate.isNotEmpty(id) && productsRemovedFromGoogle.get(index) != null) {
+                    String productId = (String)productsRemovedFromGoogle.get(index);
+                    try {
+                        int count = delegator.removeByAnd("GoodIdentification", UtilMisc.toMap("goodIdentificationTypeId", "GOOGLE_ID", "productId", productId));
+                    } catch (GenericEntityException gee) {
+                        Debug.logError("Unable to remove Google id for product [" + productId + "]: " + gee.getMessage(), module);
+                    }
+                }
+                String title = UtilXml.childElementValue(atomEntryElement, "atom:title", "");
+                List batchStatusList = UtilXml.childElementList(atomEntryElement, "batch:status");
+                Iterator batchStatusEntryElemIter = batchStatusList.iterator();
+                while (batchStatusEntryElemIter.hasNext()) {
+                    Element batchStatusEntryElement = (Element)batchStatusEntryElemIter.next();
+                    if (UtilValidate.isNotEmpty(batchStatusEntryElement.getAttribute("reason"))) {
+                        message.add(title + " " + batchStatusEntryElement.getAttribute("reason"));
+                    }
+                }
+                String errors = UtilXml.childElementValue(atomEntryElement, "batch:status", "");
+                if (UtilValidate.isNotEmpty(errors)) {
+                    message.add(title + " " + errors);
                 }
+                index++;
             }
         } catch (Exception e) {
-            Debug.logError("Exception reading response from Google", module);
-            return ServiceUtil.returnFailure(UtilProperties.getMessage(resource, "productsExportToGoogle.exceptionReadingResponseFromGoogle", locale));
+            Debug.logError("Exception reading response from Google: " + e.getMessage(), module);
+            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "productsExportToGoogle.exceptionReadingResponseFromGoogle", locale));
         }
         
-        if (message.length() > 0) {
-            Debug.logError("Error in the response from Google " + message.toString(), module);
-            message.insert(0, UtilProperties.getMessage(resource, "productsExportToGoogle.errorInTheResponseFromGoogle", locale));
-            return ServiceUtil.returnFailure(message.toString());
+        if (message.size() > 0) {
+            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "productsExportToGoogle.errorInTheResponseFromGoogle", locale), message);
         }
         return ServiceUtil.returnSuccess();
     }

Modified: ofbiz/trunk/applications/product/webapp/catalog/find/ExportForms.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/webapp/catalog/find/ExportForms.xml?view=diff&rev=562856&r1=562855&r2=562856
==============================================================================
--- ofbiz/trunk/applications/product/webapp/catalog/find/ExportForms.xml (original)
+++ ofbiz/trunk/applications/product/webapp/catalog/find/ExportForms.xml Sun Aug  5 05:28:09 2007
@@ -23,7 +23,7 @@
     <form name="ProductsExportToGoogle" type="single" target="searchExportProductListToGoogle">
         <field name="selectResult"><hidden/></field>
         <field name="webSiteUrl"><text size="50" maxlength="250"/></field>
-        <field name="imageUrl"><text size="50" maxlength="250"/></field>
+        <!--<field name="imageUrl"><text size="50" maxlength="250"/></field>-->
         <field name="actionType" widget-style="selectBox">
             <drop-down no-current-selected-key="insert">
                 <option key="insert" description="${uiLabelMap.CommonInsert}"/>
@@ -32,7 +32,7 @@
             </drop-down>
         </field>
         <field name="statusId">
-            <drop-down no-current-selected-key="draft">
+            <drop-down no-current-selected-key="publish">
                 <!--
                 <option key="deactivate" description="${uiLabelMap.ProductExportDeactivated}"/>
                 -->