svn commit: r950264 - in /ofbiz/trunk/applications/product/src/org/ofbiz/product/category: CategoryServices.java CategoryWorker.java

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

svn commit: r950264 - in /ofbiz/trunk/applications/product/src/org/ofbiz/product/category: CategoryServices.java CategoryWorker.java

doogie-3
Author: doogie
Date: Tue Jun  1 21:47:18 2010
New Revision: 950264

URL: http://svn.apache.org/viewvc?rev=950264&view=rev
Log:
Rewrote filterProductsInCategory to use larger, single queries.

Modified:
    ofbiz/trunk/applications/product/src/org/ofbiz/product/category/CategoryServices.java
    ofbiz/trunk/applications/product/src/org/ofbiz/product/category/CategoryWorker.java

Modified: ofbiz/trunk/applications/product/src/org/ofbiz/product/category/CategoryServices.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/src/org/ofbiz/product/category/CategoryServices.java?rev=950264&r1=950263&r2=950264&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/src/org/ofbiz/product/category/CategoryServices.java (original)
+++ ofbiz/trunk/applications/product/src/org/ofbiz/product/category/CategoryServices.java Tue Jun  1 21:47:18 2010
@@ -264,10 +264,7 @@ public class CategoryServices {
         if (productCategory != null) {
             try {
                 if (useCacheForMembers) {
-                    productCategoryMembers = delegator.findByAndCache(entityName, UtilMisc.toMap("productCategoryId", productCategoryId), orderByFields);
-                    if (activeOnly) {
-                        productCategoryMembers = EntityUtil.filterByDate(productCategoryMembers, true);
-                    }
+                    EntityCondition lookupCondition = EntityCondition.makeCondition(UtilMisc.toMap("productCategoryId", productCategoryId));
                     List<EntityCondition> filterConditions = FastList.newInstance();
                     if (introductionDateLimit != null) {
                         EntityCondition condition = EntityCondition.makeCondition(EntityCondition.makeCondition("introductionDate", EntityOperator.EQUALS, null), EntityOperator.OR, EntityCondition.makeCondition("introductionDate", EntityOperator.LESS_THAN_EQUAL_TO, introductionDateLimit));
@@ -277,14 +274,19 @@ public class CategoryServices {
                         EntityCondition condition = EntityCondition.makeCondition(EntityCondition.makeCondition("releaseDate", EntityOperator.EQUALS, null), EntityOperator.OR, EntityCondition.makeCondition("releaseDate", EntityOperator.LESS_THAN_EQUAL_TO, releaseDateLimit));
                         filterConditions.add(condition);
                     }
-                    if (!filterConditions.isEmpty()) {
-                        productCategoryMembers = EntityUtil.filterByCondition(productCategoryMembers, EntityCondition.makeCondition(filterConditions, EntityOperator.AND));
-                    }
 
                     // filter out the view allow before getting the sublist
                     if (UtilValidate.isNotEmpty(viewProductCategoryId)) {
-                        productCategoryMembers = CategoryWorker.filterProductsInCategory(delegator, productCategoryMembers, viewProductCategoryId);
+                        productCategoryMembers = CategoryWorker.filterProductsInCategory(delegator, lookupCondition, orderByFields, activeOnly, filterConditions, viewProductCategoryId);
                         listSize = productCategoryMembers.size();
+                    } else {
+                        productCategoryMembers = delegator.findList(entityName, lookupCondition, null, orderByFields, null, true);
+                        if (activeOnly) {
+                            productCategoryMembers = EntityUtil.filterByDate(productCategoryMembers, true);
+                        }
+                        if (!filterConditions.isEmpty()) {
+                            productCategoryMembers = EntityUtil.filterByCondition(productCategoryMembers, EntityCondition.makeCondition(filterConditions, EntityOperator.AND));
+                        }
                     }
 
                     // set the index and size

Modified: ofbiz/trunk/applications/product/src/org/ofbiz/product/category/CategoryWorker.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/src/org/ofbiz/product/category/CategoryWorker.java?rev=950264&r1=950263&r2=950264&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/src/org/ofbiz/product/category/CategoryWorker.java (original)
+++ ofbiz/trunk/applications/product/src/org/ofbiz/product/category/CategoryWorker.java Tue Jun  1 21:47:18 2010
@@ -18,15 +18,20 @@
  *******************************************************************************/
 package org.ofbiz.product.category;
 
+import java.sql.Timestamp;
 import java.util.Collection;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import javax.servlet.ServletRequest;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpSession;
 
 import javolution.util.FastList;
+import javolution.util.FastMap;
+import javolution.util.FastSet;
 
 import org.ofbiz.base.util.Debug;
 import org.ofbiz.base.util.UtilDateTime;
@@ -374,20 +379,171 @@ public class CategoryWorker {
     }
 
     public static List<GenericValue> filterProductsInCategory(Delegator delegator, List<GenericValue> valueObjects, String productCategoryId, String productIdFieldName) throws GenericEntityException {
-        List<GenericValue> newList = FastList.newInstance();
-
-        if (productCategoryId == null) return newList;
         if (valueObjects == null) return null;
+        if (productCategoryId == null) return FastList.newInstance();
+
+        EntityCondition productCategoryIdCondition = EntityCondition.makeCondition("productCategoryId", EntityOperator.EQUALS, productCategoryId);
+        Iterator<GenericValue> it = valueObjects.iterator();
+        Set<String> allowedProductIds = FastSet.newInstance();
+        Map<String, Set<String>> variants = FastMap.newInstance();
+        Timestamp now = UtilDateTime.nowTimestamp();
+        while (it.hasNext()) {
+            Set<String> lookupProductIds = FastSet.newInstance();
+            while (lookupProductIds.size() < 100 && it.hasNext()) {
+                GenericValue value = it.next();
+                lookupProductIds.add(value.getString("productId"));
+            }
+            EntityCondition condition = EntityCondition.makeCondition(EntityCondition.makeCondition("productId", EntityOperator.IN, lookupProductIds), EntityOperator.AND, productCategoryIdCondition);
+            //Debug.logInfo("query(ProductAndCategoryMember)->" + condition, module);
+            List<GenericValue> subProducts = delegator.findList("ProductAndCategoryMember", condition, null, null, null, true);
+            for (GenericValue subProduct: subProducts) {
+                String productId = subProduct.getString("productId");
+                if (EntityUtil.isValueActive(subProduct, now)) {
+                    allowedProductIds.add(productId);
+                    variants.remove(productId);
+                } else if ("Y".equals(subProduct.get("isVariant"))) {
+                    variants.put(productId, null);
+                }
+            }
+        }
+
+        return filterVariantsInCategory(delegator, now, productCategoryIdCondition, valueObjects, allowedProductIds, variants, productIdFieldName);
+    }
 
+    private static List<GenericValue> filterVariantsInCategory(Delegator delegator, Timestamp now, EntityCondition productCategoryIdCondition, List<GenericValue> valueObjects, Set<String> allowedProductIds, Map<String, Set<String>> variants, String productIdFieldName) throws GenericEntityException {
+        List<GenericValue> newList = FastList.newInstance();
+        EntityCondition assocTypeIdCondition = EntityCondition.makeCondition("productAssocTypeId", EntityOperator.EQUALS, "PRODUCT_VARIANT");
+        Map<String, Set<String>> revVariantMap = FastMap.newInstance();
+        Map<String, Set<String>> revParentMap = FastMap.newInstance();
+        // there may have been multiple rows with a variant's productId,
+        // with some of those rows not being active by date, with later
+        // rows being active.  This would cause the earlier rows to get
+        // added to variants, and the later ones to be added to
+        // allowed products.  Since we only care about finding allowed
+        // products, once something is allowed, we no longer need to be
+        // concerned about it.
+        variants.keySet().removeAll(allowedProductIds);
+        while (!variants.isEmpty()) {
+            Iterator<Map.Entry<String, Set<String>>> variantIt = variants.entrySet().iterator();
+            // this maps from possible variant child id, to original id,
+            // from the first loop above; this is so we can finally mark
+            // the original product as allowed
+            while (variantIt.hasNext()) {
+                Map.Entry<String, Set<String>> entry = variantIt.next();
+                Set<String> assocParents = entry.getValue();
+                if (assocParents == null) {
+                    // this only happens the first time thru the outer
+                    // loop.
+                    UtilMisc.addToSetInMap(entry.getKey(), revVariantMap, entry.getKey());
+                    entry.setValue(FastSet.<String>newInstance());
+                } else if (assocParents.isEmpty()) {
+                    variantIt.remove();
+                } else {
+                    for (String assocParent: assocParents) {
+                        UtilMisc.addToSetInMap(entry.getKey(), revVariantMap, assocParent);
+                    }
+                    assocParents.clear();
+                }
+            }
+            Iterator<String> variantIdIt = revVariantMap.keySet().iterator();
+            while (variantIdIt.hasNext()) {
+                Set<String> lookupProductIds = FastSet.newInstance();
+                while (variantIdIt.hasNext() && lookupProductIds.size() < 100) {
+                    lookupProductIds.add(variantIdIt.next());
+                }
+                // FIXME: use correct productAssocTypeId
+                EntityCondition condition = EntityCondition.makeCondition(EntityCondition.makeCondition("productIdTo", EntityOperator.IN, lookupProductIds), EntityOperator.AND, assocTypeIdCondition);
+                Debug.logInfo("query(ProductAndAssoc)->" + condition, module);
+                List<GenericValue> assocValues = delegator.findList("ProductAndAssoc", condition, null, null, null, true);
+                for (GenericValue assocValue: assocValues) {
+                    if (!EntityUtil.isValueActive(assocValue, now)) {
+                        continue;
+                    }
+                    String productIdTo = assocValue.getString("productIdTo");
+                    String parentProductId = assocValue.getString("productId");
+                    for (String originalProductId: revVariantMap.get(productIdTo)) {
+                        variants.get(originalProductId).add(parentProductId);
+                        //allParentProductIds.add(parentProductId);
+                        UtilMisc.addToSetInMap(originalProductId, revParentMap, parentProductId);
+                    }
+                }
+            }
+            revVariantMap.clear();
+            // at this point, the values in variants contain all the
+            // parent productIds.  Now do another membership test in
+            // the requested productCategory.
+            Iterator<String> parentIdIt = revParentMap.keySet().iterator();
+            while (parentIdIt.hasNext()) {
+                Set<String> lookupProductIds = FastSet.newInstance();
+                while (parentIdIt.hasNext() && lookupProductIds.size() < 100) {
+                    lookupProductIds.add(parentIdIt.next());
+                }
+                EntityCondition condition = EntityCondition.makeCondition(EntityCondition.makeCondition("productId", EntityOperator.IN, lookupProductIds), EntityOperator.AND, productCategoryIdCondition);
+                Debug.logInfo("query(ProductAndCategoryMember)->" + condition, module);
+                List<GenericValue> subProducts = delegator.findList("ProductAndCategoryMember", condition, null, null, null, true);
+                for (GenericValue subProduct: subProducts) {
+                    String productId = subProduct.getString("productId");
+                    if (EntityUtil.isValueActive(subProduct, now)) {
+                        // yay, found a membership
+                        for (String originalProductId: revParentMap.get(productId)) {
+                            allowedProductIds.add(originalProductId);
+                            variants.remove(originalProductId);
+                        }
+                    } else if ("Y".equals(subProduct.get("isVariant"))) {
+                        for (String originalProductId: revParentMap.get(productId)) {
+                            UtilMisc.addToSetInMap(productId, variants, originalProductId);
+                        }
+                    }
+                }
+            }
+            revParentMap.clear();
+        }
         for (GenericValue curValue: valueObjects) {
             String productId = curValue.getString(productIdFieldName);
-            if (isProductInCategory(delegator, productId, productCategoryId)) {
+            if (allowedProductIds.contains(productId)) {
                 newList.add(curValue);
             }
         }
         return newList;
     }
 
+    public static List<GenericValue> filterProductsInCategory(Delegator delegator, EntityCondition lookupCondition, List<String> orderByFields, boolean activeOnly, List<EntityCondition> filterConditions, String productCategoryId) throws GenericEntityException {
+        List<GenericValue> newList = FastList.newInstance();
+        if (productCategoryId == null) return newList;
+
+        EntityCondition productCategoryIdCondition = EntityCondition.makeCondition("productCategoryId", EntityOperator.EQUALS, productCategoryId);
+        EntityCondition assocTypeIdCondition = EntityCondition.makeCondition("productAssocTypeId", EntityOperator.EQUALS, "PRODUCT_VARIANT");
+        Set<String> allowedProductIds = FastSet.newInstance();
+        Map<String, Set<String>> variants = FastMap.newInstance();
+        Map<String, Set<String>> revVariantMap = FastMap.newInstance();
+        Map<String, Set<String>> revParentMap = FastMap.newInstance();
+        Timestamp now = UtilDateTime.nowTimestamp();
+
+        EntityCondition valueCondition = EntityCondition.makeCondition(lookupCondition, EntityOperator.AND, EntityCondition.makeCondition("secondaryProductCategoryId", EntityOperator.EQUALS, productCategoryId));
+        //Debug.logInfo("findList(ProductAndCategoryMember, " + valueCondition + ", " + orderByFields + ")", module);
+        List<GenericValue> valueObjects = delegator.findList("ProductAndCategoryMemberDouble", valueCondition, null, orderByFields, null, true);
+        //Debug.logInfo("valueObjects.size()=" + valueObjects.size(), module);
+        if (filterConditions.isEmpty()) {
+            valueObjects = EntityUtil.filterByAnd(valueObjects, filterConditions);
+        }
+        if (activeOnly) {
+            valueObjects = EntityUtil.filterByDate(valueObjects, now);
+        }
+        //Debug.logInfo("valueObjects.size()=" + valueObjects.size(), module);
+        Iterator<GenericValue> it = valueObjects.iterator();
+        while (it.hasNext()) {
+            GenericValue row = it.next();
+            String productId = row.getString("productId");
+            if (EntityUtil.isValueActive(row, now, "secondaryFromDate", "secondaryThruDate")) {
+                allowedProductIds.add(productId);
+            } else if ("Y".equals(row.get("isVariant"))) {
+                variants.put(productId, null);
+            }
+        }
+        //Debug.logInfo("allowedProductIds.size()=" + allowedProductIds.size(), module);
+        return filterVariantsInCategory(delegator, now, productCategoryIdCondition, valueObjects, allowedProductIds, variants, "productId");
+    }
+
     public static void getCategoryContentWrappers(Map<String, CategoryContentWrapper> catContentWrappers, List<GenericValue> categoryList, HttpServletRequest request) throws GenericEntityException {
         if (catContentWrappers == null || categoryList == null) {
             return;