| /******************************************************************************* |
| * 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.apache.ofbiz.product.feature; |
| |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.LinkedList; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import javax.servlet.ServletRequest; |
| import javax.servlet.http.HttpServletRequest; |
| |
| import org.apache.ofbiz.base.util.Debug; |
| import org.apache.ofbiz.base.util.UtilHttp; |
| import org.apache.ofbiz.base.util.UtilMisc; |
| import org.apache.ofbiz.base.util.UtilValidate; |
| import org.apache.ofbiz.entity.Delegator; |
| import org.apache.ofbiz.entity.GenericEntityException; |
| import org.apache.ofbiz.entity.GenericValue; |
| import org.apache.ofbiz.entity.util.EntityListIterator; |
| import org.apache.ofbiz.entity.util.EntityQuery; |
| import org.apache.ofbiz.entity.util.EntityUtil; |
| |
| /** |
| * Utilities for parametric search based on features. |
| */ |
| public class ParametricSearch { |
| |
| public static final String module = ParametricSearch.class.getName(); |
| |
| public static final int DEFAULT_PER_TYPE_MAX_SIZE = 1000; |
| |
| /** Gets all features associated with the specified category through: |
| * ProductCategory -> ProductFeatureCategoryAppl -> ProductFeatureCategory -> ProductFeature. |
| * Returns a Map of Lists of ProductFeature GenericValue objects organized by productFeatureTypeId. |
| */ |
| public static Map<String, List<GenericValue>> makeCategoryFeatureLists(String productCategoryId, Delegator delegator) { |
| return makeCategoryFeatureLists(productCategoryId, delegator, DEFAULT_PER_TYPE_MAX_SIZE); |
| } |
| |
| public static Map<String, List<GenericValue>> makeCategoryFeatureLists(String productCategoryId, Delegator delegator, int perTypeMaxSize) { |
| Map<String, Map<String, GenericValue>> productFeaturesByTypeMap = new HashMap<String, Map<String,GenericValue>>(); |
| try { |
| List<GenericValue> productFeatureCategoryAppls = EntityQuery.use(delegator).from("ProductFeatureCategoryAppl").where("productCategoryId", productCategoryId).cache(true).queryList(); |
| productFeatureCategoryAppls = EntityUtil.filterByDate(productFeatureCategoryAppls, true); |
| if (productFeatureCategoryAppls != null) { |
| for (GenericValue productFeatureCategoryAppl: productFeatureCategoryAppls) { |
| List<GenericValue> productFeatures = EntityQuery.use(delegator).from("ProductFeature").where("productFeatureCategoryId", productFeatureCategoryAppl.get("productFeatureCategoryId")).cache(true).queryList(); |
| for (GenericValue productFeature: productFeatures) { |
| String productFeatureTypeId = productFeature.getString("productFeatureTypeId"); |
| Map<String, GenericValue> featuresByType = productFeaturesByTypeMap.get(productFeatureTypeId); |
| if (featuresByType == null) { |
| featuresByType = new HashMap<String, GenericValue>(); |
| productFeaturesByTypeMap.put(productFeatureTypeId, featuresByType); |
| } |
| if (featuresByType.size() < perTypeMaxSize) { |
| featuresByType.put(productFeature.getString("productFeatureId"), productFeature); |
| } |
| } |
| } |
| } |
| } catch (GenericEntityException e) { |
| Debug.logError(e, "Error getting feature categories associated with the category with ID: " + productCategoryId, module); |
| } |
| |
| try { |
| List<GenericValue> productFeatureCatGrpAppls = EntityQuery.use(delegator).from("ProductFeatureCatGrpAppl").where("productCategoryId", productCategoryId).cache(true).queryList(); |
| productFeatureCatGrpAppls = EntityUtil.filterByDate(productFeatureCatGrpAppls, true); |
| if (productFeatureCatGrpAppls != null) { |
| for (GenericValue productFeatureCatGrpAppl: productFeatureCatGrpAppls) { |
| List<GenericValue> productFeatureGroupAppls = EntityQuery.use(delegator).from("ProductFeatureGroupAppl").where("productFeatureGroupId", productFeatureCatGrpAppl.get("productFeatureGroupId")).cache(true).queryList(); |
| for (GenericValue productFeatureGroupAppl: productFeatureGroupAppls) { |
| GenericValue productFeature = EntityQuery.use(delegator).from("ProductFeature").where("productFeatureId", productFeatureGroupAppl.get("productFeatureId")).cache().queryOne(); |
| |
| String productFeatureTypeId = productFeature.getString("productFeatureTypeId"); |
| Map<String, GenericValue> featuresByType = productFeaturesByTypeMap.get(productFeatureTypeId); |
| if (featuresByType == null) { |
| featuresByType = new HashMap<String, GenericValue>(); |
| productFeaturesByTypeMap.put(productFeatureTypeId, featuresByType); |
| } |
| if (featuresByType.size() < perTypeMaxSize) { |
| featuresByType.put(productFeature.getString("productFeatureId"), productFeature); |
| } |
| } |
| } |
| } |
| } catch (GenericEntityException e) { |
| Debug.logError(e, "Error getting feature groups associated with the category with ID: " + productCategoryId, module); |
| } |
| |
| // now before returning, order the features in each list by description |
| Map<String, List<GenericValue>> productFeaturesByTypeMapSorted = new HashMap<String, List<GenericValue>>(); |
| for (Map.Entry<String, Map<String, GenericValue>> entry: productFeaturesByTypeMap.entrySet()) { |
| List<GenericValue> sortedFeatures = EntityUtil.orderBy(entry.getValue().values(), UtilMisc.toList("description","defaultSequenceNum")); |
| productFeaturesByTypeMapSorted.put(entry.getKey(), sortedFeatures); |
| } |
| |
| return productFeaturesByTypeMapSorted; |
| } |
| |
| public static Map<String, List<GenericValue>> getAllFeaturesByType(Delegator delegator) { |
| return getAllFeaturesByType(delegator, DEFAULT_PER_TYPE_MAX_SIZE); |
| } |
| public static Map<String, List<GenericValue>> getAllFeaturesByType(Delegator delegator, int perTypeMaxSize) { |
| Map<String, List<GenericValue>> productFeaturesByTypeMap = new HashMap<String, List<GenericValue>>(); |
| try { |
| Set<String> typesWithOverflowMessages = new HashSet<String>(); |
| EntityListIterator productFeatureEli = EntityQuery.use(delegator).from("ProductFeature").orderBy("description").queryIterator(); |
| GenericValue productFeature = null; |
| while ((productFeature = productFeatureEli.next()) != null) { |
| String productFeatureTypeId = productFeature.getString("productFeatureTypeId"); |
| List<GenericValue> featuresByType = productFeaturesByTypeMap.get(productFeatureTypeId); |
| if (featuresByType == null) { |
| featuresByType = new LinkedList<GenericValue>(); |
| productFeaturesByTypeMap.put(productFeatureTypeId, featuresByType); |
| } |
| if (featuresByType.size() > perTypeMaxSize) { |
| if (!typesWithOverflowMessages.contains(productFeatureTypeId)) { |
| typesWithOverflowMessages.add(productFeatureTypeId); |
| // TODO: uh oh, how do we pass this message back? no biggie for now |
| } |
| } else { |
| featuresByType.add(productFeature); |
| } |
| } |
| productFeatureEli.close(); |
| } catch (GenericEntityException e) { |
| Debug.logError(e, "Error getting all features", module); |
| } |
| return productFeaturesByTypeMap; |
| } |
| |
| public static Map<String, String> makeFeatureIdByTypeMap(ServletRequest request) { |
| Map<String, Object> parameters = UtilHttp.getParameterMap((HttpServletRequest) request); |
| return makeFeatureIdByTypeMap(parameters); |
| } |
| |
| /** Handles parameters coming in prefixed with "pft_" where the text in the key following the prefix is a productFeatureTypeId and the value is a productFeatureId; meant to be used with drop-downs and such */ |
| public static Map<String, String> makeFeatureIdByTypeMap(Map<String, Object> parameters) { |
| Map<String, String> featureIdByType = new HashMap<String, String>(); |
| if (parameters == null) return featureIdByType; |
| |
| |
| for (Map.Entry<String, Object> entry: parameters.entrySet()) { |
| String parameterName = entry.getKey(); |
| if (parameterName.startsWith("pft_")) { |
| String productFeatureTypeId = parameterName.substring(4); |
| String productFeatureId = (String) entry.getValue(); |
| if (UtilValidate.isNotEmpty(productFeatureId)) { |
| featureIdByType.put(productFeatureTypeId, productFeatureId); |
| } |
| } |
| } |
| |
| return featureIdByType; |
| } |
| |
| /** Handles parameters coming in prefixed with "SEARCH_FEAT" where the parameter value is a productFeatureId; meant to be used with text entry boxes or check-boxes and such */ |
| public static List<String> makeFeatureIdListFromPrefixed(Map<String, Object> parameters) { |
| List<String> featureIdList = new LinkedList<String>(); |
| if (parameters == null) return featureIdList; |
| |
| for (Map.Entry<String, Object> entry: parameters.entrySet()) { |
| String parameterName = entry.getKey(); |
| if (parameterName.startsWith("SEARCH_FEAT")) { |
| String productFeatureId = (String) entry.getValue(); |
| if (UtilValidate.isNotEmpty(productFeatureId)) { |
| featureIdList.add(productFeatureId); |
| } |
| } |
| } |
| |
| return featureIdList; |
| } |
| |
| public static String makeFeatureIdByTypeString(Map<String, String> featureIdByType) { |
| if (UtilValidate.isEmpty(featureIdByType)) { |
| return ""; |
| } |
| |
| StringBuilder outSb = new StringBuilder(); |
| for (Map.Entry<String, String> entry: featureIdByType.entrySet()) { |
| if (outSb.length() > 0) { |
| outSb.append('&'); |
| } |
| String productFeatureTypeId = entry.getKey(); |
| String productFeatureId = entry.getValue(); |
| outSb.append(productFeatureTypeId); |
| outSb.append('='); |
| outSb.append(productFeatureId); |
| } |
| |
| return outSb.toString(); |
| } |
| |
| /** |
| * Handles parameters coming in prefixed with "SEARCH_PROD_FEAT_CAT" |
| * where the parameter value is a productFeatureCategoryId; |
| * meant to be used with text entry boxes or check-boxes and such |
| **/ |
| public static List<String> makeProductFeatureCategoryIdListFromPrefixed(Map<String, Object> parameters) { |
| List<String> prodFeatureCategoryIdList = new LinkedList<String>(); |
| if (parameters == null) return prodFeatureCategoryIdList; |
| |
| for (Map.Entry<String, Object> entry: parameters.entrySet()) { |
| String parameterName = entry.getKey(); |
| if (parameterName.startsWith("SEARCH_PROD_FEAT_CAT")) { |
| String productFeatureCategoryId = (String) entry.getValue(); |
| if (UtilValidate.isNotEmpty(productFeatureCategoryId)) { |
| prodFeatureCategoryIdList.add(productFeatureCategoryId); |
| } |
| } |
| } |
| return prodFeatureCategoryIdList; |
| } |
| } |