Author: jonesde
Date: Mon Mar 5 00:56:32 2007 New Revision: 514609 URL: http://svn.apache.org/viewvc?view=rev&rev=514609 Log: Initially complete implementation of the include/exclude/alwaysInclude variations for categories and features in ProductSearch; this has been tested for basic cases, but needs some testing for more complex conditions; note that UI layer things and such still need to be implemented Modified: ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductSearch.java ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductSearchSession.java Modified: ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductSearch.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductSearch.java?view=diff&rev=514609&r1=514608&r2=514609 ============================================================================== --- ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductSearch.java (original) +++ ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductSearch.java Mon Mar 5 00:56:32 2007 @@ -21,9 +21,7 @@ import java.sql.Timestamp; import java.util.ArrayList; import java.util.Collection; -import java.util.HashSet; import java.util.Iterator; -import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; @@ -31,6 +29,7 @@ import java.util.TreeSet; import javolution.util.FastList; +import javolution.util.FastSet; import org.ofbiz.base.util.Debug; import org.ofbiz.base.util.UtilDateTime; @@ -67,7 +66,7 @@ public static final String resource = "ProductUiLabels"; public static ArrayList parametricKeywordSearch(Map featureIdByType, String keywordsString, GenericDelegator delegator, String productCategoryId, String visitId, boolean anyPrefix, boolean anySuffix, boolean isAnd) { - Set featureIdSet = new HashSet(); + Set featureIdSet = FastSet.newInstance(); if (featureIdByType != null) { featureIdSet.addAll(featureIdByType.values()); } @@ -76,10 +75,10 @@ } public static ArrayList parametricKeywordSearch(Set featureIdSet, String keywordsString, GenericDelegator delegator, String productCategoryId, boolean includeSubCategories, String visitId, boolean anyPrefix, boolean anySuffix, boolean isAnd) { - List productSearchConstraintList = new LinkedList(); + List productSearchConstraintList = FastList.newInstance(); if (UtilValidate.isNotEmpty(productCategoryId)) { - productSearchConstraintList.add(new CategoryConstraint(productCategoryId, includeSubCategories)); + productSearchConstraintList.add(new CategoryConstraint(productCategoryId, includeSubCategories, null)); } if (UtilValidate.isNotEmpty(keywordsString)) { @@ -90,7 +89,7 @@ Iterator featureIdIter = featureIdSet.iterator(); while (featureIdIter.hasNext()) { String productFeatureId = (String) featureIdIter.next(); - productSearchConstraintList.add(new FeatureConstraint(productFeatureId)); + productSearchConstraintList.add(new FeatureConstraint(productFeatureId, null)); } } @@ -142,17 +141,17 @@ public static class ProductSearchContext { public int index = 1; - public List entityConditionList = new LinkedList(); - public List orderByList = new LinkedList(); + public List entityConditionList = FastList.newInstance(); + public List orderByList = FastList.newInstance(); public List fieldsToSelect = UtilMisc.toList("productId"); public DynamicViewEntity dynamicViewEntity = new DynamicViewEntity(); public boolean productIdGroupBy = false; public boolean includedKeywordSearch = false; public Timestamp nowTimestamp = UtilDateTime.nowTimestamp(); - public List keywordFixedOrSetAndList = new LinkedList(); - public Set orKeywordFixedSet = new HashSet(); - public Set andKeywordFixedSet = new HashSet(); - public List productSearchConstraintList = new LinkedList(); + public List keywordFixedOrSetAndList = FastList.newInstance(); + public Set orKeywordFixedSet = FastSet.newInstance(); + public Set andKeywordFixedSet = FastSet.newInstance(); + public List productSearchConstraintList = FastList.newInstance(); public ResultSortOrder resultSortOrder = null; public Integer resultOffset = null; public Integer maxResults = null; @@ -160,6 +159,17 @@ protected String visitId = null; protected Integer totalResults = null; + public Set includeCategoryIds = FastSet.newInstance(); + public Set excludeCategoryIds = FastSet.newInstance(); + public Set alwaysIncludeCategoryIds = FastSet.newInstance(); + + public Set includeFeatureIds = FastSet.newInstance(); + public Set excludeFeatureIds = FastSet.newInstance(); + public Set alwaysIncludeFeatureIds = FastSet.newInstance(); + + public List includeFeatureIdOrSetAndList = FastList.newInstance(); + public List alwaysIncludeFeatureIdOrSetAndList = FastList.newInstance(); + public ProductSearchContext(GenericDelegator delegator, String visitId) { this.delegator = delegator; this.visitId = visitId; @@ -291,7 +301,7 @@ dynamicViewEntity.addMemberEntity(entityAlias, "ProductKeyword"); dynamicViewEntity.addAlias(entityAlias, prefix + "Keyword", "keyword", null, null, null, null); dynamicViewEntity.addViewLink("PROD", entityAlias, Boolean.FALSE, ModelKeyMap.makeKeyMapList("productId")); - List keywordOrList = new LinkedList(); + List keywordOrList = FastList.newInstance(); Iterator keywordIter = keywordFixedOrSet.iterator(); while (keywordIter.hasNext()) { String keyword = (String) keywordIter.next(); @@ -314,10 +324,178 @@ } } + public void finishCategoryAndFeatureConstraints() { + if (includeCategoryIds.size() == 0 && excludeCategoryIds.size() == 0 && alwaysIncludeCategoryIds.size() == 0 && + includeFeatureIds.size() == 0 && excludeFeatureIds.size() == 0 && alwaysIncludeFeatureIds.size() == 0 && + includeFeatureIdOrSetAndList.size() == 0) { + return; + } + + // create new view members with logic: + // ((each Id = category includes AND Id IN feature includes) AND (Id NOT IN category excludes AND Id NOT IN feature excludes)) + // OR (each Id = category alwaysIncludes AND each Id = feature alwaysIncludes) + List incExcCondList = FastList.newInstance(); + EntityCondition incExcCond = null; + + List alwIncCondList = FastList.newInstance(); + EntityCondition alwIncCond = null; + + EntityCondition topCond = null; + + Iterator includeCategoryIdIter = includeCategoryIds.iterator(); + while (includeCategoryIdIter.hasNext()) { + String includeCategoryId = (String) includeCategoryIdIter.next(); + String categoryPrefix = "pcm" + this.index; + String entityAlias = "PCM" + this.index; + this.index++; + + this.dynamicViewEntity.addMemberEntity(entityAlias, "ProductCategoryMember"); + this.dynamicViewEntity.addAlias(entityAlias, categoryPrefix + "ProductCategoryId", "productCategoryId", null, null, null, null); + this.dynamicViewEntity.addAlias(entityAlias, categoryPrefix + "FromDate", "fromDate", null, null, null, null); + this.dynamicViewEntity.addAlias(entityAlias, categoryPrefix + "ThruDate", "thruDate", null, null, null, null); + this.dynamicViewEntity.addViewLink("PROD", entityAlias, Boolean.FALSE, ModelKeyMap.makeKeyMapList("productId")); + incExcCondList.add(new EntityExpr(new EntityExpr(categoryPrefix + "ThruDate", EntityOperator.EQUALS, null), EntityOperator.OR, new EntityExpr(categoryPrefix + "ThruDate", EntityOperator.GREATER_THAN, this.nowTimestamp))); + incExcCondList.add(new EntityExpr(categoryPrefix + "FromDate", EntityOperator.LESS_THAN, this.nowTimestamp)); + incExcCondList.add(new EntityExpr(categoryPrefix + "ProductCategoryId", EntityOperator.EQUALS, includeCategoryId)); + } + Iterator includeFeatureIdIter = includeFeatureIds.iterator(); + while (includeFeatureIdIter.hasNext()) { + String includeFeatureId = (String) includeFeatureIdIter.next(); + String featurePrefix = "pfa" + this.index; + String entityAlias = "PFA" + this.index; + this.index++; + + this.dynamicViewEntity.addMemberEntity(entityAlias, "ProductFeatureAppl"); + this.dynamicViewEntity.addAlias(entityAlias, featurePrefix + "ProductFeatureId", "productFeatureId", null, null, null, null); + this.dynamicViewEntity.addAlias(entityAlias, featurePrefix + "FromDate", "fromDate", null, null, null, null); + this.dynamicViewEntity.addAlias(entityAlias, featurePrefix + "ThruDate", "thruDate", null, null, null, null); + this.dynamicViewEntity.addViewLink("PROD", entityAlias, Boolean.FALSE, ModelKeyMap.makeKeyMapList("productId")); + incExcCondList.add(new EntityExpr(new EntityExpr(featurePrefix + "ThruDate", EntityOperator.EQUALS, null), EntityOperator.OR, new EntityExpr(featurePrefix + "ThruDate", EntityOperator.GREATER_THAN, this.nowTimestamp))); + incExcCondList.add(new EntityExpr(featurePrefix + "FromDate", EntityOperator.LESS_THAN, this.nowTimestamp)); + incExcCondList.add(new EntityExpr(featurePrefix + "ProductFeatureId", EntityOperator.EQUALS, includeFeatureId)); + } + + + if (excludeCategoryIds.size() != 0) { + String categoryPrefix = "pcm" + this.index; + String entityAlias = "PCM" + this.index; + this.index++; + + this.dynamicViewEntity.addMemberEntity(entityAlias, "ProductCategoryMember"); + this.dynamicViewEntity.addAlias(entityAlias, categoryPrefix + "ProductCategoryId", "productCategoryId", null, null, null, null); + this.dynamicViewEntity.addAlias(entityAlias, categoryPrefix + "FromDate", "fromDate", null, null, null, null); + this.dynamicViewEntity.addAlias(entityAlias, categoryPrefix + "ThruDate", "thruDate", null, null, null, null); + this.dynamicViewEntity.addViewLink("PROD", entityAlias, Boolean.FALSE, ModelKeyMap.makeKeyMapList("productId")); + incExcCondList.add(new EntityExpr(new EntityExpr(categoryPrefix + "ThruDate", EntityOperator.EQUALS, null), EntityOperator.OR, new EntityExpr(categoryPrefix + "ThruDate", EntityOperator.GREATER_THAN, this.nowTimestamp))); + incExcCondList.add(new EntityExpr(categoryPrefix + "FromDate", EntityOperator.LESS_THAN, this.nowTimestamp)); + incExcCondList.add(new EntityExpr(categoryPrefix + "ProductCategoryId", EntityOperator.NOT_IN, excludeCategoryIds)); + } + if (excludeFeatureIds.size() != 0) { + String featurePrefix = "pfa" + this.index; + String entityAlias = "PFA" + this.index; + this.index++; + + this.dynamicViewEntity.addMemberEntity(entityAlias, "ProductFeatureAppl"); + this.dynamicViewEntity.addAlias(entityAlias, featurePrefix + "ProductFeatureId", "productFeatureId", null, null, null, null); + this.dynamicViewEntity.addAlias(entityAlias, featurePrefix + "FromDate", "fromDate", null, null, null, null); + this.dynamicViewEntity.addAlias(entityAlias, featurePrefix + "ThruDate", "thruDate", null, null, null, null); + this.dynamicViewEntity.addViewLink("PROD", entityAlias, Boolean.FALSE, ModelKeyMap.makeKeyMapList("productId")); + incExcCondList.add(new EntityExpr(new EntityExpr(featurePrefix + "ThruDate", EntityOperator.EQUALS, null), EntityOperator.OR, new EntityExpr(featurePrefix + "ThruDate", EntityOperator.GREATER_THAN, this.nowTimestamp))); + incExcCondList.add(new EntityExpr(featurePrefix + "FromDate", EntityOperator.LESS_THAN, this.nowTimestamp)); + incExcCondList.add(new EntityExpr(featurePrefix + "ProductFeatureId", EntityOperator.NOT_IN, excludeFeatureIds)); + } + + if (alwaysIncludeCategoryIds.size() != 0) { + String categoryPrefix = "pcm" + this.index; + String entityAlias = "PCM" + this.index; + this.index++; + + this.dynamicViewEntity.addMemberEntity(entityAlias, "ProductCategoryMember"); + this.dynamicViewEntity.addAlias(entityAlias, categoryPrefix + "ProductCategoryId", "productCategoryId", null, null, null, null); + this.dynamicViewEntity.addAlias(entityAlias, categoryPrefix + "FromDate", "fromDate", null, null, null, null); + this.dynamicViewEntity.addAlias(entityAlias, categoryPrefix + "ThruDate", "thruDate", null, null, null, null); + this.dynamicViewEntity.addViewLink("PROD", entityAlias, Boolean.FALSE, ModelKeyMap.makeKeyMapList("productId")); + alwIncCondList.add(new EntityExpr(new EntityExpr(categoryPrefix + "ThruDate", EntityOperator.EQUALS, null), EntityOperator.OR, new EntityExpr(categoryPrefix + "ThruDate", EntityOperator.GREATER_THAN, this.nowTimestamp))); + alwIncCondList.add(new EntityExpr(categoryPrefix + "FromDate", EntityOperator.LESS_THAN, this.nowTimestamp)); + alwIncCondList.add(new EntityExpr(categoryPrefix + "ProductCategoryId", EntityOperator.IN, alwaysIncludeCategoryIds)); + } + if (alwaysIncludeFeatureIds.size() != 0) { + String featurePrefix = "pfa" + this.index; + String entityAlias = "PFA" + this.index; + this.index++; + + this.dynamicViewEntity.addMemberEntity(entityAlias, "ProductFeatureAppl"); + this.dynamicViewEntity.addAlias(entityAlias, featurePrefix + "ProductFeatureId", "productFeatureId", null, null, null, null); + this.dynamicViewEntity.addAlias(entityAlias, featurePrefix + "FromDate", "fromDate", null, null, null, null); + this.dynamicViewEntity.addAlias(entityAlias, featurePrefix + "ThruDate", "thruDate", null, null, null, null); + this.dynamicViewEntity.addViewLink("PROD", entityAlias, Boolean.FALSE, ModelKeyMap.makeKeyMapList("productId")); + alwIncCondList.add(new EntityExpr(new EntityExpr(featurePrefix + "ThruDate", EntityOperator.EQUALS, null), EntityOperator.OR, new EntityExpr(featurePrefix + "ThruDate", EntityOperator.GREATER_THAN, this.nowTimestamp))); + alwIncCondList.add(new EntityExpr(featurePrefix + "FromDate", EntityOperator.LESS_THAN, this.nowTimestamp)); + alwIncCondList.add(new EntityExpr(featurePrefix + "ProductFeatureId", EntityOperator.IN, alwaysIncludeFeatureIds)); + } + + // handle includeFeatureIdOrSetAndList and alwaysIncludeFeatureIdOrSetAndList + + Iterator includeFeatureIdOrSetAndIter = includeFeatureIdOrSetAndList.iterator(); + while (includeFeatureIdOrSetAndIter.hasNext()) { + Set includeFeatureIdOrSet = (Set) includeFeatureIdOrSetAndIter.next(); + String featurePrefix = "pfa" + this.index; + String entityAlias = "PFA" + this.index; + this.index++; + + this.dynamicViewEntity.addMemberEntity(entityAlias, "ProductFeatureAppl"); + this.dynamicViewEntity.addAlias(entityAlias, featurePrefix + "ProductFeatureId", "productFeatureId", null, null, null, null); + this.dynamicViewEntity.addAlias(entityAlias, featurePrefix + "FromDate", "fromDate", null, null, null, null); + this.dynamicViewEntity.addAlias(entityAlias, featurePrefix + "ThruDate", "thruDate", null, null, null, null); + this.dynamicViewEntity.addViewLink("PROD", entityAlias, Boolean.FALSE, ModelKeyMap.makeKeyMapList("productId")); + incExcCondList.add(new EntityExpr(new EntityExpr(featurePrefix + "ThruDate", EntityOperator.EQUALS, null), EntityOperator.OR, new EntityExpr(featurePrefix + "ThruDate", EntityOperator.GREATER_THAN, this.nowTimestamp))); + incExcCondList.add(new EntityExpr(featurePrefix + "FromDate", EntityOperator.LESS_THAN, this.nowTimestamp)); + incExcCondList.add(new EntityExpr(featurePrefix + "ProductFeatureId", EntityOperator.EQUALS, includeFeatureIdOrSet)); + } + + Iterator alwaysIncludeFeatureIdOrSetAndIter = alwaysIncludeFeatureIdOrSetAndList.iterator(); + while (alwaysIncludeFeatureIdOrSetAndIter.hasNext()) { + Set alwaysIncludeFeatureIdOrSet = (Set) alwaysIncludeFeatureIdOrSetAndIter.next(); + String featurePrefix = "pfa" + this.index; + String entityAlias = "PFA" + this.index; + this.index++; + + this.dynamicViewEntity.addMemberEntity(entityAlias, "ProductFeatureAppl"); + this.dynamicViewEntity.addAlias(entityAlias, featurePrefix + "ProductFeatureId", "productFeatureId", null, null, null, null); + this.dynamicViewEntity.addAlias(entityAlias, featurePrefix + "FromDate", "fromDate", null, null, null, null); + this.dynamicViewEntity.addAlias(entityAlias, featurePrefix + "ThruDate", "thruDate", null, null, null, null); + this.dynamicViewEntity.addViewLink("PROD", entityAlias, Boolean.FALSE, ModelKeyMap.makeKeyMapList("productId")); + alwIncCondList.add(new EntityExpr(new EntityExpr(featurePrefix + "ThruDate", EntityOperator.EQUALS, null), EntityOperator.OR, new EntityExpr(featurePrefix + "ThruDate", EntityOperator.GREATER_THAN, this.nowTimestamp))); + alwIncCondList.add(new EntityExpr(featurePrefix + "FromDate", EntityOperator.LESS_THAN, this.nowTimestamp)); + alwIncCondList.add(new EntityExpr(featurePrefix + "ProductFeatureId", EntityOperator.EQUALS, alwaysIncludeFeatureIdOrSet)); + } + + if (incExcCondList.size() > 0) { + incExcCond = new EntityConditionList(incExcCondList, EntityOperator.AND); + } + if (alwIncCondList.size() > 0) { + alwIncCond = new EntityConditionList(alwIncCondList, EntityOperator.AND); + } + + if (incExcCond != null && alwIncCond != null) { + topCond = new EntityExpr(incExcCond, EntityOperator.OR, alwIncCond); + } else if (incExcCond != null) { + topCond = incExcCond; + } else if (alwIncCond != null) { + topCond = alwIncCond; + } + + this.entityConditionList.add(topCond); + + Debug.logInfo("topCond=" + topCond, module); + } + public EntityListIterator doQuery(GenericDelegator delegator) { // handle the now assembled or and and keyword fixed lists this.finishKeywordConstraints(); + this.finishCategoryAndFeatureConstraints(); + if (resultSortOrder != null) { resultSortOrder.setSortOrder(this); } @@ -397,7 +575,7 @@ int numRetreived = 1; int duplicatesFound = 0; - Set productIdSet = new HashSet(); + Set productIdSet = FastSet.newInstance(); productIds.add(searchResult.getString("productId")); productIdSet.add(searchResult.getString("productId")); @@ -585,17 +763,26 @@ public static final String constraintName = "Category"; protected String productCategoryId; protected boolean includeSubCategories; + /** This is a tri-state variable: null = Include, true = Exclude, false = AlwaysInclude */ + protected Boolean exclude; - public CategoryConstraint(String productCategoryId, boolean includeSubCategories) { + /** + * + * @param productCategoryId + * @param includeSubCategories + * @param exclude This is a tri-state variable: null = Include, true = Exclude, false = AlwaysInclude + */ + public CategoryConstraint(String productCategoryId, boolean includeSubCategories, Boolean exclude) { this.productCategoryId = productCategoryId; this.includeSubCategories = includeSubCategories; + this.exclude = exclude; } public void addConstraint(ProductSearchContext productSearchContext) { List productCategoryIdList = null; if (includeSubCategories) { // find all sub-categories recursively, make a Set of productCategoryId - Set productCategoryIdSet = new HashSet(); + Set productCategoryIdSet = FastSet.newInstance(); ProductSearch.getAllSubCategoryIds(productCategoryId, productCategoryIdSet, productSearchContext.getDelegator(), productSearchContext.nowTimestamp); productCategoryIdList = FastList.newInstance(); productCategoryIdList.addAll(productCategoryIdSet); @@ -603,20 +790,15 @@ productCategoryIdList = UtilMisc.toList(productCategoryId); } - // make index based values and increment - String entityAlias = "PCM" + productSearchContext.index; - String prefix = "pcm" + productSearchContext.index; - productSearchContext.index++; - - productSearchContext.dynamicViewEntity.addMemberEntity(entityAlias, "ProductCategoryMember"); - productSearchContext.dynamicViewEntity.addAlias(entityAlias, prefix + "ProductCategoryId", "productCategoryId", null, null, null, null); - productSearchContext.dynamicViewEntity.addAlias(entityAlias, prefix + "FromDate", "fromDate", null, null, null, null); - productSearchContext.dynamicViewEntity.addAlias(entityAlias, prefix + "ThruDate", "thruDate", null, null, null, null); - productSearchContext.dynamicViewEntity.addViewLink("PROD", entityAlias, Boolean.FALSE, ModelKeyMap.makeKeyMapList("productId")); - productSearchContext.entityConditionList.add(new EntityExpr(prefix + "ProductCategoryId", EntityOperator.IN, productCategoryIdList)); - productSearchContext.entityConditionList.add(new EntityExpr(new EntityExpr(prefix + "ThruDate", EntityOperator.EQUALS, null), EntityOperator.OR, new EntityExpr(prefix + "ThruDate", EntityOperator.GREATER_THAN, productSearchContext.nowTimestamp))); - productSearchContext.entityConditionList.add(new EntityExpr(prefix + "FromDate", EntityOperator.LESS_THAN, productSearchContext.nowTimestamp)); - + // just add to global sets + if (exclude == null) { + productSearchContext.includeCategoryIds.addAll(productCategoryIdList); + } else if (exclude.equals(Boolean.TRUE)) { + productSearchContext.excludeCategoryIds.addAll(productCategoryIdList); + } else if (exclude.equals(Boolean.FALSE)) { + productSearchContext.alwaysIncludeCategoryIds.addAll(productCategoryIdList); + } + // add in productSearchConstraint, don't worry about the productSearchResultId or constraintSeqId, those will be fill in later productSearchContext.productSearchConstraintList.add(productSearchContext.getDelegator().makeValue("ProductSearchConstraint", UtilMisc.toMap("constraintName", constraintName, "infoString", this.productCategoryId, "includeSubCategories", this.includeSubCategories ? "Y" : "N"))); } @@ -675,25 +857,28 @@ public static class FeatureConstraint extends ProductSearchConstraint { public static final String constraintName = "Feature"; protected String productFeatureId; + /** This is a tri-state variable: null = Include, true = Exclude, false = AlwaysInclude */ + protected Boolean exclude; - public FeatureConstraint(String productFeatureId) { + /** + * + * @param productFeatureId + * @param exclude This is a tri-state variable: null = Include, true = Exclude, false = AlwaysInclude + */ + public FeatureConstraint(String productFeatureId, Boolean exclude) { this.productFeatureId = productFeatureId; + this.exclude = exclude; } public void addConstraint(ProductSearchContext productSearchContext) { - // make index based values and increment - String entityAlias = "PFA" + productSearchContext.index; - String prefix = "pfa" + productSearchContext.index; - productSearchContext.index++; - - productSearchContext.dynamicViewEntity.addMemberEntity(entityAlias, "ProductFeatureAppl"); - productSearchContext.dynamicViewEntity.addAlias(entityAlias, prefix + "ProductFeatureId", "productFeatureId", null, null, null, null); - productSearchContext.dynamicViewEntity.addAlias(entityAlias, prefix + "FromDate", "fromDate", null, null, null, null); - productSearchContext.dynamicViewEntity.addAlias(entityAlias, prefix + "ThruDate", "thruDate", null, null, null, null); - productSearchContext.dynamicViewEntity.addViewLink("PROD", entityAlias, Boolean.FALSE, ModelKeyMap.makeKeyMapList("productId")); - productSearchContext.entityConditionList.add(new EntityExpr(prefix + "ProductFeatureId", EntityOperator.EQUALS, productFeatureId)); - productSearchContext.entityConditionList.add(new EntityExpr(new EntityExpr(prefix + "ThruDate", EntityOperator.EQUALS, null), EntityOperator.OR, new EntityExpr(prefix + "ThruDate", EntityOperator.GREATER_THAN, productSearchContext.nowTimestamp))); - productSearchContext.entityConditionList.add(new EntityExpr(prefix + "FromDate", EntityOperator.LESS_THAN, productSearchContext.nowTimestamp)); + // just add to global sets + if (exclude == null) { + productSearchContext.includeFeatureIds.add(productFeatureId); + } else if (exclude.equals(Boolean.TRUE)) { + productSearchContext.excludeFeatureIds.add(productFeatureId); + } else if (exclude.equals(Boolean.FALSE)) { + productSearchContext.alwaysIncludeFeatureIds.add(productFeatureId); + } // add in productSearchConstraint, don't worry about the productSearchResultId or constraintSeqId, those will be fill in later productSearchContext.productSearchConstraintList.add(productSearchContext.getDelegator().makeValue("ProductSearchConstraint", UtilMisc.toMap("constraintName", constraintName, "infoString", this.productFeatureId))); @@ -743,25 +928,29 @@ public static class FeatureSetConstraint extends ProductSearchConstraint { public static final String constraintName = "Feature Set"; protected Set productFeatureIdSet; + /** This is a tri-state variable: null = Include, true = Exclude, false = AlwaysInclude */ + protected Boolean exclude; - public FeatureSetConstraint(Collection productFeatureIdSet) { - this.productFeatureIdSet = new HashSet(productFeatureIdSet); + /** + * + * @param productFeatureIdSet + * @param exclude This is a tri-state variable: null = Include, true = Exclude, false = AlwaysInclude + */ + public FeatureSetConstraint(Collection productFeatureIdSet, Boolean exclude) { + this.productFeatureIdSet = FastSet.newInstance(); + this.productFeatureIdSet.addAll(productFeatureIdSet); + this.exclude = exclude; } public void addConstraint(ProductSearchContext productSearchContext) { - // make index based values and increment - String entityAlias = "PFA" + productSearchContext.index; - String prefix = "pfa" + productSearchContext.index; - productSearchContext.index++; - - productSearchContext.dynamicViewEntity.addMemberEntity(entityAlias, "ProductFeatureAppl"); - productSearchContext.dynamicViewEntity.addAlias(entityAlias, prefix + "ProductFeatureId", "productFeatureId", null, null, null, null); - productSearchContext.dynamicViewEntity.addAlias(entityAlias, prefix + "FromDate", "fromDate", null, null, null, null); - productSearchContext.dynamicViewEntity.addAlias(entityAlias, prefix + "ThruDate", "thruDate", null, null, null, null); - productSearchContext.dynamicViewEntity.addViewLink("PROD", entityAlias, Boolean.FALSE, ModelKeyMap.makeKeyMapList("productId")); - productSearchContext.entityConditionList.add(new EntityExpr(prefix + "ProductFeatureId", EntityOperator.IN, productFeatureIdSet)); - productSearchContext.entityConditionList.add(new EntityExpr(new EntityExpr(prefix + "ThruDate", EntityOperator.EQUALS, null), EntityOperator.OR, new EntityExpr(prefix + "ThruDate", EntityOperator.GREATER_THAN, productSearchContext.nowTimestamp))); - productSearchContext.entityConditionList.add(new EntityExpr(prefix + "FromDate", EntityOperator.LESS_THAN, productSearchContext.nowTimestamp)); + // just add to global sets + if (exclude == null) { + productSearchContext.includeFeatureIdOrSetAndList.add(productFeatureIdSet); + } else if (exclude.equals(Boolean.TRUE)) { + productSearchContext.excludeFeatureIds.addAll(productFeatureIdSet); + } else if (exclude.equals(Boolean.FALSE)) { + productSearchContext.alwaysIncludeFeatureIdOrSetAndList.add(productFeatureIdSet); + } // add in productSearchConstraint, don't worry about the productSearchResultId or constraintSeqId, those will be fill in later StringBuffer featureIdInfo = new StringBuffer(); @@ -890,7 +1079,7 @@ expandedSet.add(keyword); } Set fixedSet = KeywordSearchUtil.fixKeywordsForSearch(expandedSet, anyPrefix, anySuffix, removeStems, isAnd); - Set fixedKeywordSet = new HashSet(); + Set fixedKeywordSet = FastSet.newInstance(); fixedKeywordSet.addAll(fixedSet); productSearchContext.keywordFixedOrSetAndList.add(fixedKeywordSet); } Modified: ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductSearchSession.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductSearchSession.java?view=diff&rev=514609&r1=514608&r2=514609 ============================================================================== --- ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductSearchSession.java (original) +++ ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductSearchSession.java Mon Mar 5 00:56:32 2007 @@ -364,7 +364,7 @@ ProductSearchOptions.setResultSortOrder(resultSortOrder, session); } - public static void searchAddFeatureIdConstraints(Collection featureIds, HttpServletRequest request) { + public static void searchAddFeatureIdConstraints(Collection featureIds, Boolean exclude, HttpServletRequest request) { HttpSession session = request.getSession(); if (featureIds == null || featureIds.size() == 0) { return; @@ -372,7 +372,7 @@ Iterator featureIdIter = featureIds.iterator(); while (featureIdIter.hasNext()) { String productFeatureId = (String) featureIdIter.next(); - searchAddConstraint(new FeatureConstraint(productFeatureId), session); + searchAddConstraint(new FeatureConstraint(productFeatureId, exclude), session); } } @@ -424,7 +424,9 @@ if (UtilValidate.isNotEmpty((String) parameters.get("SEARCH_CATEGORY_ID"))) { String searchCategoryId = (String) parameters.get("SEARCH_CATEGORY_ID"); String searchSubCategories = (String) parameters.get("SEARCH_SUB_CATEGORIES"); - searchAddConstraint(new ProductSearch.CategoryConstraint(searchCategoryId, !"N".equals(searchSubCategories)), session); + String searchCategoryExc = (String) parameters.get("SEARCH_CATEGORY_EXC"); + Boolean exclude = UtilValidate.isEmpty(searchCategoryExc) ? null : new Boolean(!"N".equals(searchCategoryExc)); + searchAddConstraint(new ProductSearch.CategoryConstraint(searchCategoryId, !"N".equals(searchSubCategories), exclude), session); constraintsChanged = true; } @@ -432,7 +434,9 @@ if (UtilValidate.isNotEmpty((String) parameters.get("SEARCH_CATEGORY_ID" + catNum))) { String searchCategoryId = (String) parameters.get("SEARCH_CATEGORY_ID" + catNum); String searchSubCategories = (String) parameters.get("SEARCH_SUB_CATEGORIES" + catNum); - searchAddConstraint(new ProductSearch.CategoryConstraint(searchCategoryId, !"N".equals(searchSubCategories)), session); + String searchCategoryExc = (String) parameters.get("SEARCH_CATEGORY_EXC" + catNum); + Boolean exclude = UtilValidate.isEmpty(searchCategoryExc) ? null : new Boolean(!"N".equals(searchCategoryExc)); + searchAddConstraint(new ProductSearch.CategoryConstraint(searchCategoryId, !"N".equals(searchSubCategories), exclude), session); constraintsChanged = true; } } @@ -468,18 +472,25 @@ } } - // if features were specified by ID add a constraint for each - List featureIdList = ParametricSearch.makeFeatureIdListFromPrefixed(parameters); - if (featureIdList.size() > 0) { - constraintsChanged = true; - searchAddFeatureIdConstraints(featureIdList, request); + Iterator parameterNameIter = parameters.keySet().iterator(); + while (parameterNameIter.hasNext()) { + String parameterName = (String) parameterNameIter.next(); + if (parameterName.startsWith("SEARCH_FEAT")) { + String productFeatureId = (String) parameters.get(parameterName); + if (productFeatureId != null && productFeatureId.length() > 0) { + String paramNameExt = parameterName.substring("SEARCH_FEAT".length() + 1); + String searchCategoryExc = (String) parameters.get("SEARCH_FEAT_EXC" + paramNameExt); + Boolean exclude = UtilValidate.isEmpty(searchCategoryExc) ? null : new Boolean(!"N".equals(searchCategoryExc)); + searchAddConstraint(new ProductSearch.FeatureConstraint(productFeatureId, exclude), session); + } + } } // if features were selected add a constraint for each Map featureIdByType = ParametricSearch.makeFeatureIdByTypeMap(parameters); if (featureIdByType.size() > 0) { constraintsChanged = true; - searchAddFeatureIdConstraints(featureIdByType.values(), request); + searchAddFeatureIdConstraints(featureIdByType.values(), null, request); } // add a supplier to the search @@ -551,7 +562,7 @@ String prodCatalogId = CatalogWorker.getCurrentCatalogId(request); String viewProductCategoryId = CatalogWorker.getCatalogViewAllowCategoryId(delegator, prodCatalogId); if (UtilValidate.isNotEmpty(viewProductCategoryId)) { - ProductSearchConstraint viewAllowConstraint = new CategoryConstraint(viewProductCategoryId, true); + ProductSearchConstraint viewAllowConstraint = new CategoryConstraint(viewProductCategoryId, true, null); searchAddConstraint(viewAllowConstraint, session); // not consider this a change for now, shouldn't change often: constraintsChanged = true; } @@ -702,6 +713,12 @@ searchParamString.append(categoriesCount); searchParamString.append("="); searchParamString.append(cc.includeSubCategories ? "Y" : "N"); + if (cc.exclude != null) { + searchParamString.append("&SEARCH_CATEGORY_EXC"); + searchParamString.append(categoriesCount); + searchParamString.append("="); + searchParamString.append(cc.exclude.booleanValue() ? "Y" : "N"); + } } else if (psc instanceof ProductSearch.FeatureConstraint) { ProductSearch.FeatureConstraint fc = (ProductSearch.FeatureConstraint) psc; featuresCount++; @@ -714,6 +731,12 @@ searchParamString.append(featuresCount); searchParamString.append("="); searchParamString.append(fc.productFeatureId); + if (fc.exclude != null) { + searchParamString.append("&SEARCH_FEAT_EXC"); + searchParamString.append(categoriesCount); + searchParamString.append("="); + searchParamString.append(fc.exclude.booleanValue() ? "Y" : "N"); + } /* No way to specify parameters for these right now, so table until later } else if (psc instanceof ProductSearch.FeatureSetConstraint) { ProductSearch.FeatureSetConstraint fsc = (ProductSearch.FeatureSetConstraint) psc; |
Free forum by Nabble | Edit this page |