You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by ja...@apache.org on 2007/07/03 11:42:11 UTC

svn commit: r552765 - in /ofbiz/trunk/applications/product: config/ servicedef/ src/org/ofbiz/product/product/ webapp/catalog/WEB-INF/ webapp/catalog/find/ widget/catalog/

Author: jacopoc
Date: Tue Jul  3 02:42:10 2007
New Revision: 552765

URL: http://svn.apache.org/viewvc?view=rev&rev=552765
Log:
Applied patch (with some minor changes) by Marco Risaliti (OFBIZ-1095), as a first step in the implementation of product export features to Google.

Added:
    ofbiz/trunk/applications/product/config/productsExport.properties   (with props)
    ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductsExportToGoogle.java   (with props)
    ofbiz/trunk/applications/product/webapp/catalog/find/ExportForms.xml   (with props)
Modified:
    ofbiz/trunk/applications/product/servicedef/services.xml
    ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/controller.xml
    ofbiz/trunk/applications/product/webapp/catalog/find/keywordsearch.ftl
    ofbiz/trunk/applications/product/widget/catalog/FindScreens.xml

Added: ofbiz/trunk/applications/product/config/productsExport.properties
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/config/productsExport.properties?view=auto&rev=552765
==============================================================================
--- ofbiz/trunk/applications/product/config/productsExport.properties (added)
+++ ofbiz/trunk/applications/product/config/productsExport.properties Tue Jul  3 02:42:10 2007
@@ -0,0 +1,26 @@
+###############################################################################
+# 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.
+###############################################################################
+####
+# OFBiz Product Export Settings
+####
+productsExport.google.developerKey=
+productsExport.google.authenticationUrl=https://www.google.com/accounts/ClientLogin
+productsExport.google.accountEmail=
+productsExport.google.accountPassword=
+productsExport.google.postItemsUrl= http://www.google.com/base/feeds/items/batch

Propchange: ofbiz/trunk/applications/product/config/productsExport.properties
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/applications/product/config/productsExport.properties
------------------------------------------------------------------------------
    svn:keywords = "Date Rev Author URL Id"

Propchange: ofbiz/trunk/applications/product/config/productsExport.properties
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: ofbiz/trunk/applications/product/servicedef/services.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/servicedef/services.xml?view=diff&rev=552765&r1=552764&r2=552765
==============================================================================
--- ofbiz/trunk/applications/product/servicedef/services.xml (original)
+++ ofbiz/trunk/applications/product/servicedef/services.xml Tue Jul  3 02:42:10 2007
@@ -1115,4 +1115,13 @@
         <permission-service service-name="productGenericPermission" main-action="DELETE"/>
         <auto-attributes include="pk" mode="IN" optional="false"/>
     </service>
+    <!-- Products Export Services -->    
+    <service name="exportToGoogle" engine="java"
+             location="org.ofbiz.product.product.ProductsExportToGoogle" invoke="exportToGoogle" auth="true">
+        <description>Export products to Google Base</description>
+        <attribute type="String" mode="IN" name="products" optional="false"/>
+        <attribute type="String" mode="IN" name="webSiteUrl" optional="false"/>
+        <attribute type="String" mode="IN" name="imageUrl" optional="false"/>
+        <attribute type="String" mode="IN" name="trackingCodeId" optional="true"/>
+    </service>
 </services>

Added: 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=auto&rev=552765
==============================================================================
--- ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductsExportToGoogle.java (added)
+++ ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductsExportToGoogle.java Tue Jul  3 02:42:10 2007
@@ -0,0 +1,338 @@
+/*******************************************************************************
+ * 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.product.product;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javolution.util.FastMap;
+
+import org.apache.xml.serialize.OutputFormat;
+import org.apache.xml.serialize.XMLSerializer;
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.StringUtil;
+import org.ofbiz.base.util.UtilFormatOut;
+import org.ofbiz.base.util.UtilMisc;
+import org.ofbiz.base.util.UtilProperties;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.base.util.UtilXml;
+import org.ofbiz.entity.GenericDelegator;
+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.ServiceUtil;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+public class ProductsExportToGoogle {
+    
+    private static final String resource = "ProductUiLabels";
+    private static final String module = ProductsExportToGoogle.class.getName();
+    private static final String xmlHeader = "<?xml version=\'1.0\' encoding='UTF-8'?>\n";
+
+    public static Map exportToGoogle(DispatchContext dctx, Map context) {
+        Locale locale = (Locale) context.get("locale");
+        try {
+            String configString = "productsExport.properties";
+                            
+            // get the Developer Key
+            String developerKey = UtilProperties.getPropertyValue(configString, "productsExport.google.developerKey");
+            
+            // get the Authentication Url
+            String authenticationUrl = UtilProperties.getPropertyValue(configString, "productsExport.google.authenticationUrl");
+            
+            // get the Google Account Email
+            String accountEmail = UtilProperties.getPropertyValue(configString, "productsExport.google.accountEmail");
+            
+            // get the Google Account Password
+            String accountPassword = UtilProperties.getPropertyValue(configString, "productsExport.google.accountPassword");
+            
+            // get the Url to Post Items
+            String postItemsUrl = UtilProperties.getPropertyValue(configString, "productsExport.google.postItemsUrl");
+        
+            StringBuffer dataItemsXml = new StringBuffer();
+            
+            if (!ServiceUtil.isFailure(buildDataItemsXml(dctx, context, dataItemsXml))) { 
+                String token = authenticate(authenticationUrl, accountEmail, accountPassword);
+
+                if (token != null) {    
+                    Map result = postItem(token, postItemsUrl, developerKey, dataItemsXml);
+                    if (ServiceUtil.isFailure(result))
+                        return ServiceUtil.returnFailure(ServiceUtil.getErrorMessage(result));
+                } else {
+                    Debug.logError("Error during authentication to Google Account", module);
+                    return ServiceUtil.returnFailure(UtilProperties.getMessage(resource, "productsExportToGoogle.errorDuringAuthenticationToGoogle", locale));
+                }
+            }
+        } catch (Exception e) {        
+            Debug.logError("Exception in exportToGoogle", module);
+            return ServiceUtil.returnFailure(UtilProperties.getMessage(resource, "productsExportToGoogle.exceptionInExportToGoogle", locale));
+        }
+        return ServiceUtil.returnSuccess(UtilProperties.getMessage(resource, "productsExportToGoogle.productItemsSentCorrecltyToGoogle", locale));
+    }
+   
+    private static String authenticate(String authenticationUrl, String accountEmail, String accountPassword) {
+        String postOutput = null;
+        String token = null;
+        try {
+            postOutput = makeLoginRequest(authenticationUrl, accountEmail, accountPassword);
+        } catch (IOException e) {
+            Debug.logError("Could not connect to authentication server: " + e.toString(), module);
+            return token;
+        }
+
+        // Parse the result of the login request. If everything went fine, the 
+        // response will look like
+        //      HTTP/1.0 200 OK
+        //      Server: GFE/1.3
+        //      Content-Type: text/plain 
+        //      SID=DQAAAGgA...7Zg8CTN
+        //      LSID=DQAAAGsA...lk8BBbG
+        //      Auth=DQAAAGgA...dk3fA5N
+        // so all we need to do is look for "Auth" and get the token that comes after it
+
+        StringTokenizer tokenizer = new StringTokenizer(postOutput, "=\n ");
+      
+        while (tokenizer.hasMoreElements()) {
+            if (tokenizer.nextToken().equals("Auth")) {
+                if (tokenizer.hasMoreElements()) {
+                    token = tokenizer.nextToken(); 
+                }
+                break;
+            }
+        }
+        if (token == null) {
+            Debug.logError("Authentication error. Response from server:\n" + postOutput, module);
+        }
+        return token;
+    }
+
+    private static String makeLoginRequest(String authenticationUrl, String accountEmail, String accountPassword) throws IOException {
+        // Open connection
+        URL url = new URL(authenticationUrl);
+        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
+      
+        // Set properties of the connection
+        urlConnection.setRequestMethod("POST");
+        urlConnection.setDoInput(true);
+        urlConnection.setDoOutput(true);
+        urlConnection.setUseCaches(false);
+        urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+    
+        // Form the POST parameters
+        StringBuffer content = new StringBuffer();
+        content.append("Email=").append(URLEncoder.encode(accountEmail, "UTF-8"));
+        content.append("&Passwd=").append(URLEncoder.encode(accountPassword, "UTF-8"));
+        content.append("&source=").append(URLEncoder.encode("Google Base data API for OFBiz", "UTF-8"));
+        content.append("&service=").append(URLEncoder.encode("gbase", "UTF-8"));
+
+        OutputStream outputStream = urlConnection.getOutputStream();
+        outputStream.write(content.toString().getBytes("UTF-8"));
+        outputStream.close();
+    
+        // Retrieve the output
+        int responseCode = urlConnection.getResponseCode();
+        InputStream inputStream;
+        if (responseCode == HttpURLConnection.HTTP_OK) {
+            inputStream = urlConnection.getInputStream();
+        } else {
+            inputStream = urlConnection.getErrorStream();
+        }
+    
+        return toString(inputStream);
+    }
+    
+    private static String toString(InputStream inputStream) throws IOException {
+        String string;
+        StringBuilder outputBuilder = new StringBuilder();
+        if (inputStream != null) {
+            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
+            while (null != (string = reader.readLine())) {
+                outputBuilder.append(string).append('\n');
+            }
+        }
+        return outputBuilder.toString();
+    }
+    
+    private static Map postItem(String token, String postItemsUrl, String developerKey, StringBuffer dataItems) throws IOException {
+        HttpURLConnection connection = (HttpURLConnection)(new URL(postItemsUrl)).openConnection();
+      
+        connection.setDoInput(true);
+        connection.setDoOutput(true);
+        connection.setRequestMethod("POST");
+        connection.setRequestProperty("Content-Type", "application/atom+xml");
+        connection.setRequestProperty("Authorization", "GoogleLogin auth=" + token);
+        connection.setRequestProperty("X-Google-Key", "key=" + developerKey);
+    
+        OutputStream outputStream = connection.getOutputStream();
+        outputStream.write(dataItems.toString().getBytes());
+        outputStream.close();
+    
+        int responseCode = connection.getResponseCode();
+        InputStream inputStream;
+        Map result = FastMap.newInstance();
+        if (responseCode == HttpURLConnection.HTTP_CREATED) {
+            inputStream = connection.getInputStream();
+            result = ServiceUtil.returnSuccess(toString(inputStream));
+        } else if (responseCode == HttpURLConnection.HTTP_OK) {
+            inputStream = connection.getInputStream();
+            result = ServiceUtil.returnFailure(toString(inputStream));
+        } else {
+            inputStream = connection.getErrorStream();
+            result = ServiceUtil.returnFailure(toString(inputStream));
+        }
+        return result;
+    }
+    
+    private static Map buildDataItemsXml(DispatchContext dctx, Map context, StringBuffer dataItemsXml) {
+        Locale locale = (Locale)context.get("locale");
+        try {
+             GenericDelegator delegator = dctx.getDelegator();
+             LocalDispatcher dispatcher = dctx.getDispatcher();
+             String products = (String)context.get("products");
+             String webSiteUrl = (String)context.get("webSiteUrl");
+             String imageUrl = (String)context.get("imageUrl");
+             String trackingCodeId = (String)context.get("trackingCodeId");
+             
+             // Get the list of products to be exported to Google Base
+             List productsList  = delegator.findByCondition("Product", new EntityExpr("productId", EntityOperator.IN, StringUtil.split(products, ",")), null, null);
+             
+             // Get the tracking code
+             if (UtilValidate.isEmpty(trackingCodeId) || "_NA_".equals(trackingCodeId)) {
+                 trackingCodeId = "";
+             } else {
+                 trackingCodeId = "?atc=" + trackingCodeId;
+             }
+             
+             try {
+                 Document feedDocument = UtilXml.makeEmptyXmlDocument("feed");
+                 Element feedElem = feedDocument.getDocumentElement();
+                 feedElem.setAttribute("xmlns", "http://www.w3.org/2005/Atom");
+                 feedElem.setAttribute("xmlns:openSearch", "http://a9.com/-/spec/opensearchrss/1.0/");
+                 feedElem.setAttribute("xmlns:g", "http://base.google.com/ns/1.0");
+                 feedElem.setAttribute("xmlns:batch", "http://schemas.google.com/gdata/batch");
+                 
+                 dataItemsXml.append(xmlHeader);
+                 
+                 // Iterate the product list getting all the relevant data
+                 Iterator productsListItr = productsList.iterator();
+                 while(productsListItr.hasNext()) {
+                     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;
+                     String title = UtilFormatOut.encodeXmlValue(prod.getString("productName"));
+                     String description = UtilFormatOut.encodeXmlValue(prod.getString("description"));
+                     String image_link = "";
+                     if (UtilValidate.isNotEmpty(prod.getString("largeImageUrl"))) {
+                         image_link = imageUrl + prod.getString("largeImageUrl");
+                     }
+                     
+                     Element entryElem = UtilXml.addChildElement(feedElem, "entry", feedDocument);
+                     Element batchElem = UtilXml.addChildElement(entryElem, "batch:operation", feedDocument);
+                     batchElem.setAttribute("type", "insert");
+                     
+                     UtilXml.addChildElementValue(entryElem, "title", title, feedDocument);
+                     
+                     Element contentElem = UtilXml.addChildElementValue(entryElem, "content", description, feedDocument);
+                     contentElem.setAttribute("type", "xhtml");
+                     
+                     UtilXml.addChildElementValue(entryElem, "id", link, feedDocument);
+                     
+                     Element linkElem = UtilXml.addChildElement(entryElem, "link", feedDocument);
+                     linkElem.setAttribute("rel", "alternate");
+                     linkElem.setAttribute("type", "text/html");
+                     linkElem.setAttribute("href", link);
+                     
+                     UtilXml.addChildElementValue(entryElem, "g:item_type", "products", feedDocument);
+                     UtilXml.addChildElementValue(entryElem, "g:price", price, feedDocument);
+                     
+                     if (UtilValidate.isNotEmpty(image_link)) {
+                         UtilXml.addChildElementValue(entryElem, "g:image_link", image_link, feedDocument);
+                     }
+                     
+                     Element appControlElem = UtilXml.addChildElement(entryElem, "app:control", feedDocument);
+                     appControlElem.setAttribute("xmlns:app", "http://purl.org/atom/app#");
+                     UtilXml.addChildElementValue(appControlElem, "app:draft", "yes", feedDocument);
+                 }
+                 OutputStream os = new ByteArrayOutputStream();
+                 OutputFormat format = new OutputFormat();
+                 format.setOmitDocumentType(true);
+                 format.setOmitXMLDeclaration(true);
+                 format.setIndenting(false);
+                 XMLSerializer serializer = new XMLSerializer(os, format);
+                 serializer.asDOMSerializer();
+                 serializer.serialize(feedDocument.getDocumentElement());
+                 
+                 dataItemsXml.append(os.toString());
+             } catch (Exception e) {
+                 Debug.logError("Exception during building data items to Google", module);
+                 return ServiceUtil.returnFailure(UtilProperties.getMessage(resource, "productsExportToGoogle.exceptionDuringBuildingDataItemsToGoogle", locale));
+             }
+         } 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();
+    }
+
+    private static String getProductPrice(LocalDispatcher dispatcher, GenericValue product) {
+        String priceString = null;
+        try {
+            Map map = dispatcher.runSync("calculateProductPrice", UtilMisc.toMap("product", product));
+            boolean validPriceFound = ((Boolean)map.get("validPriceFound")).booleanValue();
+            boolean isSale = ((Boolean)map.get("isSale")).booleanValue();
+            if (validPriceFound) {
+                // "price" is a mandatory output
+                priceString = UtilFormatOut.formatPrice((Double)map.get("price"));
+            }
+            /*
+            if (isSale && null != map.get("price")) {
+                priceString = UtilFormatOut.formatPrice((Double)map.get("price"));
+            } else if (null != map.get("defaultPrice")) {
+                priceString = UtilFormatOut.formatPrice((Double)map.get("defaultPrice"));
+            } else if (null != map.get("listPrice")) {
+                priceString = UtilFormatOut.formatPrice((Double)map.get("listPrice"));
+            }
+             */
+        } catch(Exception e){
+            Debug.logError("Exception calculating price for product [" + product.getString("productId") + "]", module);
+        }
+        return priceString;
+    }
+}

Propchange: ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductsExportToGoogle.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductsExportToGoogle.java
------------------------------------------------------------------------------
    svn:keywords = "Date Rev Author URL Id"

Propchange: ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductsExportToGoogle.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

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?view=diff&rev=552765&r1=552764&r2=552765
==============================================================================
--- ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/controller.xml (original)
+++ ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/controller.xml Tue Jul  3 02:42:10 2007
@@ -2373,6 +2373,18 @@
     <request-map uri="LookupFacilityLocation"><security auth="true" https="true"/><response name="success" type="view" value="LookupFacilityLocation"/></request-map>
     <request-map uri="LookupWorkEffort"><security https="true" auth="true"/><response name="success" type="view" value="LookupWorkEffort"/></request-map>      
 
+    <request-map uri="ProductsExportToGoogle">
+        <security https="true" auth="true"/>
+        <response name="success" type="view" value="ProductsExportToGoogle"/>
+    </request-map>
+    
+    <request-map uri="exportProductsToGoogle">
+        <security https="true" auth="true"/>
+        <event type="service" path="" invoke="exportToGoogle"/>
+        <response name="success" type="view" value="ProductsExportToGoogle"/>
+        <response name="error" type="view" value="ProductsExportToGoogle"/>
+    </request-map>
+    
     <!-- end of request mappings -->
 
     <!-- View Mappings -->
@@ -2504,6 +2516,8 @@
     <view-map name="ListShipmentMethodTypes" type="screen" page="component://product/widget/catalog/ShippingScreens.xml#ListShipmentMethodTypes"/>
     <view-map name="ListCarrierShipmentMethods" type="screen" page="component://product/widget/catalog/ShippingScreens.xml#ListCarrierShipmentMethods"/>
 
+    <view-map name="ProductsExportToGoogle" type="screen" page="component://product/widget/catalog/FindScreens.xml#ProductsExportToGoogle"/>
+   
     <!-- Lookup request mappings -->
     <view-map name="LookupContent" page="component://content/widget/content/ContentScreens.xml#LookupContent" type="screen"/>
     <view-map name="LookupFixedAsset" type="screen" page="component://accounting/widget/LookupScreens.xml#LookupFixedAsset"/>

Added: 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=auto&rev=552765
==============================================================================
--- ofbiz/trunk/applications/product/webapp/catalog/find/ExportForms.xml (added)
+++ ofbiz/trunk/applications/product/webapp/catalog/find/ExportForms.xml Tue Jul  3 02:42:10 2007
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+
+<forms xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+        xsi:noNamespaceSchemaLocation="http://www.ofbiz.org/dtds/widget-form.xsd">
+
+    <form name="ProductsExportToGoogle" type="single" target="exportProductsToGoogle">
+        <field name="products"><hidden/></field>
+        <field name="webSiteUrl"><text size="50" maxlength="250"/></field>
+        <field name="imageUrl"><text size="50" maxlength="250"/></field>
+        <field name="trackingCodeId" widget-style="selectBox">
+            <drop-down no-current-selected-key="_NA_">
+                <option key="_NA_" description="${uiLabelMap.ProductExportNoTrackingRequested}"/>
+                <entity-options entity-name="TrackingCode" description="${description}">
+                    <entity-order-by field-name="description"/>
+                </entity-options>
+            </drop-down>
+        </field>
+        <field name="submitButton" title="${uiLabelMap.ProductExportToGoogle}"><submit button-type="button"/></field>
+    </form>
+</forms>

Propchange: ofbiz/trunk/applications/product/webapp/catalog/find/ExportForms.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/applications/product/webapp/catalog/find/ExportForms.xml
------------------------------------------------------------------------------
    svn:keywords = "Date Rev Author URL Id"

Propchange: ofbiz/trunk/applications/product/webapp/catalog/find/ExportForms.xml
------------------------------------------------------------------------------
    svn:mime-type = text/xml

Modified: ofbiz/trunk/applications/product/webapp/catalog/find/keywordsearch.ftl
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/webapp/catalog/find/keywordsearch.ftl?view=diff&rev=552765&r1=552764&r2=552765
==============================================================================
--- ofbiz/trunk/applications/product/webapp/catalog/find/keywordsearch.ftl (original)
+++ ofbiz/trunk/applications/product/webapp/catalog/find/keywordsearch.ftl Tue Jul  3 02:42:10 2007
@@ -67,21 +67,43 @@
             }
         }
     }
+    
+    function exportToGoogle() {
+        var products = new Array();
+        var idx = 0;
+        for (var i = 0; i < document.products.elements.length; i++) {
+            var element = document.products.elements[i];
+            var sname = element.name.substring(0,12);
+            var product = "product" + element.name.substring(12);
+            if (sname == "selectResult" && element.checked) {
+                products[idx] = document.products.elements[product].value;
+                idx++;
+            }
+        }
+        if (idx == 0) {
+            alert('At least one product has to be selected');
+        } else {
+            document.exportToGoogle.action="<@o...@ofbizUrl>";
+            document.exportToGoogle.products.value = products;
+            document.exportToGoogle.submit();
+        }
+    }
 </script>
-<center>
+<form name="products">
   <table width="100%" cellpadding="0" cellspacing="0">
     <#assign listIndex = lowIndex>
     <#list productIds as productId><#-- note that there is no boundary range because that is being done before the list is put in the content -->
       <#assign product = delegator.findByPrimaryKey("Product", Static["org.ofbiz.base.util.UtilMisc"].toMap("productId", productId))>
       <tr>
         <td>
+          <input type="hidden" name="product${productId_index}" value="${productId}"/>
           <input type="checkbox" name="selectResult${productId_index}" onchange="checkProductToBagTextArea(this, '${productId}');"/>
           <a href="<@o...@ofbizUrl>" class="buttontext">[${productId}] ${(product.internalName)?if_exists}</a>
         </td>
       </tr>
     </#list>
   </table>
-</center>
+<form>
 </#if>
 
 <#if productIds?has_content>
@@ -188,8 +210,8 @@
 <div class="tabletext">
 <form method="post" action="" name="searchShowParams">
   <#assign searchParams = Static["org.ofbiz.product.product.ProductSearchSession"].makeSearchParametersString(session)>
-  <div><b>Plain Search Parameters:</b><input type="text" size="60" name="searchParameters" value="${searchParams}" class="inputBox"></div>
-  <div><b>HTML Search Parameters:</b><input type="text" size="60" name="searchParameters" value="${searchParams?html}" class="inputBox"></div>
+  <div><b>${uiLabelMap.ProductPlainSearchParameters}:</b><input type="text" size="60" name="searchParameters" value="${searchParams}" class="inputBox"></div>
+  <div><b>${uiLabelMap.ProductHtmlSearchParameters}:</b><input type="text" size="60" name="searchParameters" value="${searchParams?html}" class="inputBox"></div>
   <input type="hidden" name="clearSearch" value="N">
 </form>
 </div>
@@ -197,5 +219,11 @@
 <hr class="sepbar"/>
 <div class="tabletext">
   <b>${uiLabelMap.ProductSearchExportProductList}:</b> <a href="<@o...@ofbizUrl>" class="buttontext">${uiLabelMap.ProductSearchExport}</a>
+  <#if productIds?has_content>
+    <a href="javascript:exportToGoogle();" class="buttontext">${uiLabelMap.ProductExportToGoogle}</a>
+    <form method="post" name="exportToGoogle">
+        <input type="hidden" name="products">
+    </form>
+  </#if>
 </div>
 </#if>

Modified: ofbiz/trunk/applications/product/widget/catalog/FindScreens.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/widget/catalog/FindScreens.xml?view=diff&rev=552765&r1=552764&r2=552765
==============================================================================
--- ofbiz/trunk/applications/product/widget/catalog/FindScreens.xml (original)
+++ ofbiz/trunk/applications/product/widget/catalog/FindScreens.xml Tue Jul  3 02:42:10 2007
@@ -132,4 +132,23 @@
             </widgets>
         </section>
     </screen>
+    
+    <screen name="ProductsExportToGoogle">
+        <section>
+            <actions>
+                <set field="titleProperty" value="PageTitleProductsExportToGoogle"/>
+            </actions>
+            <widgets>
+                <decorator-screen name="CommonProductDecorator" location="${parameters.mainDecoratorLocation}">
+                    <decorator-section name="body">
+                        <container>
+                            <label style="head1">${uiLabelMap.PageTitleProductsExportToGoogle}</label>
+                        </container>
+                        <include-form name="ProductsExportToGoogle" location="component://product/webapp/catalog/find/ExportForms.xml"/>
+                    </decorator-section>
+                </decorator-screen>
+            </widgets>
+        </section>  
+    </screen>
+            
 </screens>