001: /*******************************************************************************
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: *******************************************************************************/package org.ofbiz.product.category;
019:
020: import java.util.Collection;
021: import java.util.Iterator;
022: import java.util.LinkedList;
023: import java.util.List;
024: import java.util.Map;
025:
026: import javax.servlet.ServletRequest;
027: import javax.servlet.http.HttpServletRequest;
028: import javax.servlet.http.HttpSession;
029: import javax.servlet.jsp.PageContext;
030:
031: import javolution.util.FastList;
032:
033: import org.ofbiz.base.util.Debug;
034: import org.ofbiz.base.util.UtilDateTime;
035: import org.ofbiz.base.util.UtilFormatOut;
036: import org.ofbiz.base.util.UtilHttp;
037: import org.ofbiz.base.util.UtilMisc;
038: import org.ofbiz.base.util.UtilValidate;
039: import org.ofbiz.entity.GenericDelegator;
040: import org.ofbiz.entity.GenericEntityException;
041: import org.ofbiz.entity.GenericValue;
042: import org.ofbiz.entity.condition.EntityCondition;
043: import org.ofbiz.entity.condition.EntityConditionList;
044: import org.ofbiz.entity.condition.EntityExpr;
045: import org.ofbiz.entity.condition.EntityOperator;
046: import org.ofbiz.entity.util.EntityUtil;
047: import org.ofbiz.product.product.ProductWorker;
048:
049: /**
050: * CategoryWorker - Worker class to reduce code in JSPs.
051: */
052: public class CategoryWorker {
053:
054: public static final String module = CategoryWorker.class.getName();
055:
056: public static String getCatalogTopCategory(PageContext pageContext,
057: String defaultTopCategory) {
058: return getCatalogTopCategory(pageContext.getRequest(),
059: defaultTopCategory);
060: }
061:
062: public static String getCatalogTopCategory(ServletRequest request,
063: String defaultTopCategory) {
064: HttpServletRequest httpRequest = (HttpServletRequest) request;
065: Map requestParameters = UtilHttp.getParameterMap(httpRequest);
066: String topCatName = null;
067: boolean fromSession = false;
068:
069: // first see if a new category was specified as a parameter
070: topCatName = (String) requestParameters
071: .get("CATALOG_TOP_CATEGORY");
072: // if no parameter, try from session
073: if (topCatName == null) {
074: topCatName = (String) httpRequest.getSession()
075: .getAttribute("CATALOG_TOP_CATEGORY");
076: if (topCatName != null)
077: fromSession = true;
078: }
079: // if nothing else, just use a default top category name
080: if (topCatName == null)
081: topCatName = defaultTopCategory;
082: if (topCatName == null)
083: topCatName = "CATALOG1";
084:
085: if (!fromSession) {
086: if (Debug.infoOn())
087: Debug.logInfo(
088: "[CategoryWorker.getCatalogTopCategory] Setting new top category: "
089: + topCatName, module);
090: httpRequest.getSession().setAttribute(
091: "CATALOG_TOP_CATEGORY", topCatName);
092: }
093: return topCatName;
094: }
095:
096: public static void getCategoriesWithNoParent(
097: PageContext pageContext, String attributeName) {
098: getCategoriesWithNoParent(pageContext.getRequest(),
099: attributeName);
100: }
101:
102: public static void getCategoriesWithNoParent(
103: ServletRequest request, String attributeName) {
104: GenericDelegator delegator = (GenericDelegator) request
105: .getAttribute("delegator");
106: Collection results = new LinkedList();
107:
108: try {
109: Collection allCategories = delegator
110: .findAll("ProductCategory");
111:
112: if (allCategories == null)
113: return;
114: Iterator aciter = allCategories.iterator();
115:
116: while (aciter.hasNext()) {
117: GenericValue curCat = (GenericValue) aciter.next();
118: Collection parentCats = curCat
119: .getRelatedCache("CurrentProductCategoryRollup");
120:
121: if (parentCats == null || parentCats.size() <= 0)
122: results.add(curCat);
123: }
124: } catch (GenericEntityException e) {
125: Debug.logWarning(e, module);
126: }
127: request.setAttribute(attributeName, results);
128: }
129:
130: public static void getRelatedCategories(PageContext pageContext,
131: String attributeName, boolean limitView) {
132: getRelatedCategories(pageContext.getRequest(), attributeName,
133: limitView);
134: }
135:
136: public static void getRelatedCategories(ServletRequest request,
137: String attributeName, boolean limitView) {
138: Map requestParameters = UtilHttp
139: .getParameterMap((HttpServletRequest) request);
140: String requestId = null;
141:
142: requestId = UtilFormatOut.checkNull((String) requestParameters
143: .get("catalog_id"), (String) requestParameters
144: .get("CATALOG_ID"), (String) requestParameters
145: .get("category_id"), (String) requestParameters
146: .get("CATEGORY_ID"));
147:
148: if (requestId.equals(""))
149: return;
150: if (Debug.infoOn())
151: Debug.logInfo(
152: "[CategoryWorker.getRelatedCategories] RequestID: "
153: + requestId, module);
154: getRelatedCategories(request, attributeName, requestId,
155: limitView);
156: }
157:
158: public static void getRelatedCategories(PageContext pageContext,
159: String attributeName, String parentId, boolean limitView) {
160: getRelatedCategories(pageContext.getRequest(), attributeName,
161: parentId, limitView);
162: }
163:
164: public static void getRelatedCategories(ServletRequest request,
165: String attributeName, String parentId, boolean limitView) {
166: getRelatedCategories(request, attributeName, parentId,
167: limitView, false);
168: }
169:
170: public static void getRelatedCategories(ServletRequest request,
171: String attributeName, String parentId, boolean limitView,
172: boolean excludeEmpty) {
173: List categories = getRelatedCategoriesRet(request,
174: attributeName, parentId, limitView, excludeEmpty);
175:
176: if (categories.size() > 0)
177: request.setAttribute(attributeName, categories);
178: }
179:
180: public static List getRelatedCategoriesRet(PageContext pageContext,
181: String attributeName, String parentId, boolean limitView) {
182: return getRelatedCategoriesRet(pageContext.getRequest(),
183: attributeName, parentId, limitView);
184: }
185:
186: public static List getRelatedCategoriesRet(ServletRequest request,
187: String attributeName, String parentId, boolean limitView) {
188: return getRelatedCategoriesRet(request, attributeName,
189: parentId, limitView, false);
190: }
191:
192: public static List getRelatedCategoriesRet(ServletRequest request,
193: String attributeName, String parentId, boolean limitView,
194: boolean excludeEmpty) {
195: List categories = FastList.newInstance();
196:
197: if (Debug.verboseOn())
198: Debug.logVerbose(
199: "[CategoryWorker.getRelatedCategories] ParentID: "
200: + parentId, module);
201:
202: GenericDelegator delegator = (GenericDelegator) request
203: .getAttribute("delegator");
204: List rollups = null;
205:
206: try {
207: rollups = delegator
208: .findByAndCache("ProductCategoryRollup",
209: UtilMisc.toMap("parentProductCategoryId",
210: parentId), UtilMisc
211: .toList("sequenceNum"));
212: if (limitView) {
213: rollups = EntityUtil.filterByDate(rollups, true);
214: }
215: } catch (GenericEntityException e) {
216: Debug.logWarning(e.getMessage(), module);
217: rollups = null;
218: }
219: if (rollups != null && rollups.size() > 0) {
220: // Debug.log("Rollup size: " + rollups.size(), module);
221: Iterator ri = rollups.iterator();
222:
223: while (ri.hasNext()) {
224: GenericValue parent = (GenericValue) ri.next();
225: // Debug.log("Adding child of: " + parent.getString("parentProductCategoryId"), module);
226: GenericValue cv = null;
227:
228: try {
229: cv = parent
230: .getRelatedOneCache("CurrentProductCategory");
231: } catch (GenericEntityException e) {
232: Debug.logWarning(e.getMessage(), module);
233: cv = null;
234: }
235: if (cv != null) {
236: if (excludeEmpty) {
237: if (!isCategoryEmpty(cv)) {
238: //Debug.log("Child : " + cv.getString("productCategoryId") + " is not empty.", module);
239: categories.add(cv);
240: categories.addAll(getRelatedCategoriesRet(
241: request, attributeName,
242: cv.getString("productCategoryId"),
243: limitView, excludeEmpty));
244: }
245: } else {
246: categories.add(cv);
247: categories.addAll(getRelatedCategoriesRet(
248: request, attributeName,
249: cv.getString("productCategoryId"),
250: limitView, excludeEmpty));
251: }
252: }
253: }
254: }
255: return categories;
256: }
257:
258: public static boolean isCategoryEmpty(GenericValue category) {
259: boolean empty = true;
260: long members = categoryMemberCount(category);
261: //Debug.log("Category : " + category.get("productCategoryId") + " has " + members + " members", module);
262: if (members > 0) {
263: empty = false;
264: }
265:
266: if (empty) {
267: long rollups = categoryRollupCount(category);
268: //Debug.log("Category : " + category.get("productCategoryId") + " has " + rollups + " rollups", module);
269: if (rollups > 0) {
270: empty = false;
271: }
272: }
273:
274: return empty;
275: }
276:
277: public static long categoryMemberCount(GenericValue category) {
278: if (category == null)
279: return 0;
280: GenericDelegator delegator = category.getDelegator();
281: long count = 0;
282: try {
283: count = delegator.findCountByCondition(
284: "ProductCategoryMember", buildCountCondition(
285: "productCategoryId", category
286: .getString("productCategoryId")),
287: null);
288: } catch (GenericEntityException e) {
289: Debug.logError(e, module);
290: }
291: return count;
292: }
293:
294: public static long categoryRollupCount(GenericValue category) {
295: if (category == null)
296: return 0;
297: GenericDelegator delegator = category.getDelegator();
298: long count = 0;
299: try {
300: count = delegator.findCountByCondition(
301: "ProductCategoryRollup", buildCountCondition(
302: "parentProductCategoryId", category
303: .getString("productCategoryId")),
304: null);
305: } catch (GenericEntityException e) {
306: Debug.logError(e, module);
307: }
308: return count;
309: }
310:
311: private static EntityCondition buildCountCondition(
312: String fieldName, String fieldValue) {
313: List orCondList = FastList.newInstance();
314: orCondList.add(new EntityExpr("thruDate",
315: EntityOperator.GREATER_THAN, UtilDateTime
316: .nowTimestamp()));
317: orCondList.add(new EntityExpr("thruDate",
318: EntityOperator.EQUALS, null));
319: EntityCondition orCond = new EntityConditionList(orCondList,
320: EntityOperator.OR);
321:
322: List andCondList = FastList.newInstance();
323: andCondList.add(new EntityExpr("fromDate",
324: EntityOperator.LESS_THAN, UtilDateTime.nowTimestamp()));
325: andCondList.add(new EntityExpr(fieldName,
326: EntityOperator.EQUALS, fieldValue));
327: andCondList.add(orCond);
328: EntityCondition andCond = new EntityConditionList(andCondList,
329: EntityOperator.AND);
330:
331: return andCond;
332: }
333:
334: public static void setTrail(PageContext pageContext,
335: String currentCategory) {
336: setTrail(pageContext.getRequest(), currentCategory);
337: }
338:
339: public static void setTrail(ServletRequest request,
340: String currentCategory) {
341: Map requestParameters = UtilHttp
342: .getParameterMap((HttpServletRequest) request);
343: String previousCategory = (String) requestParameters
344: .get("pcategory");
345:
346: if (Debug.verboseOn())
347: Debug.logVerbose(
348: "[CategoryWorker.setTrail] Start: previousCategory="
349: + previousCategory + " currentCategory="
350: + currentCategory, module);
351:
352: // if there is no current category, just return and do nothing to that the last settings will stay
353: if (currentCategory == null || currentCategory.length() <= 0)
354: return;
355:
356: // always get the last crumb list
357: List crumb = getTrail(request);
358:
359: if (crumb == null) {
360: crumb = FastList.newInstance();
361: }
362:
363: // if no previous category was specified, check to see if currentCategory is in the list
364: if (previousCategory == null || previousCategory.length() <= 0) {
365: if (crumb.contains(currentCategory)) {
366: // if cur category is in crumb, remove everything after it and return
367: int cindex = crumb.lastIndexOf(currentCategory);
368:
369: if (cindex < (crumb.size() - 1)) {
370: for (int i = crumb.size() - 1; i > cindex; i--) {
371: String deadCat = (String) crumb.remove(i);
372:
373: if (Debug.infoOn())
374: Debug.logInfo(
375: "[CategoryWorker.setTrail] Removed after current category index: "
376: + i + " catname: "
377: + deadCat, module);
378: }
379: }
380: return;
381: } else {
382: // current category is not in the list, and no previous category was specified, go back to the beginning
383: crumb.clear();
384: crumb.add("TOP");
385: if (UtilValidate.isNotEmpty(previousCategory)) {
386: crumb.add(previousCategory);
387: }
388: if (Debug.infoOn())
389: Debug.logInfo(
390: "[CategoryWorker.setTrail] Starting new list, added TOP and previousCategory: "
391: + previousCategory, module);
392: }
393: }
394:
395: if (!crumb.contains(previousCategory)) {
396: // previous category was NOT in the list, ERROR, start over
397: if (Debug.infoOn())
398: Debug
399: .logInfo(
400: "[CategoryWorker.setTrail] ERROR: previousCategory ("
401: + previousCategory
402: + ") was not in the crumb list, position is lost, starting over with TOP",
403: module);
404: crumb.clear();
405: crumb.add("TOP");
406: if (UtilValidate.isNotEmpty(previousCategory)) {
407: crumb.add(previousCategory);
408: }
409: } else {
410: // remove all categories after the previous category, preparing for adding the current category
411: int index = crumb.indexOf(previousCategory);
412:
413: if (index < (crumb.size() - 1)) {
414: for (int i = crumb.size() - 1; i > index; i--) {
415: String deadCat = (String) crumb.remove(i);
416:
417: if (Debug.infoOn())
418: Debug.logInfo(
419: "[CategoryWorker.setTrail] Removed after previous category index: "
420: + i + " catname: " + deadCat,
421: module);
422: }
423: }
424: }
425:
426: // add the current category to the end of the list
427: crumb.add(currentCategory);
428: if (Debug.verboseOn())
429: Debug.logVerbose(
430: "[CategoryWorker.setTrail] Continuing list: Added currentCategory: "
431: + currentCategory, module);
432: setTrail(request, crumb);
433: }
434:
435: public static List getTrail(PageContext pageContext) {
436: return getTrail(pageContext.getRequest());
437: }
438:
439: public static List getTrail(ServletRequest request) {
440: HttpSession session = ((HttpServletRequest) request)
441: .getSession();
442: List crumb = (List) session.getAttribute("_BREAD_CRUMB_TRAIL_");
443: return crumb;
444: }
445:
446: public static List setTrail(PageContext pageContext, List crumb) {
447: return setTrail(pageContext.getRequest(), crumb);
448: }
449:
450: public static List setTrail(ServletRequest request, List crumb) {
451: HttpSession session = ((HttpServletRequest) request)
452: .getSession();
453: session.setAttribute("_BREAD_CRUMB_TRAIL_", crumb);
454: return crumb;
455: }
456:
457: public static boolean checkTrailItem(PageContext pageContext,
458: String category) {
459: return checkTrailItem(pageContext.getRequest(), category);
460: }
461:
462: public static boolean checkTrailItem(ServletRequest request,
463: String category) {
464: List crumb = getTrail(request);
465:
466: if (crumb != null && crumb.contains(category))
467: return true;
468: else
469: return false;
470: }
471:
472: public static String lastTrailItem(PageContext pageContext) {
473: return lastTrailItem(pageContext.getRequest());
474: }
475:
476: public static String lastTrailItem(ServletRequest request) {
477: List crumb = getTrail(request);
478:
479: if (crumb != null && crumb.size() > 0) {
480: return (String) crumb.get(crumb.size() - 1);
481: } else {
482: return null;
483: }
484: }
485:
486: public static boolean isProductInCategory(
487: GenericDelegator delegator, String productId,
488: String productCategoryId) throws GenericEntityException {
489: if (productCategoryId == null)
490: return false;
491: if (productId == null || productId.length() == 0)
492: return false;
493:
494: List productCategoryMembers = EntityUtil.filterByDate(delegator
495: .findByAndCache("ProductCategoryMember", UtilMisc
496: .toMap("productCategoryId", productCategoryId,
497: "productId", productId)), true);
498: if (productCategoryMembers == null
499: || productCategoryMembers.size() == 0) {
500: //before giving up see if this is a variant product, and if so look up the virtual product and check it...
501: GenericValue product = delegator.findByPrimaryKeyCache(
502: "Product", UtilMisc.toMap("productId", productId));
503: List productAssocs = ProductWorker
504: .getVariantVirtualAssocs(product);
505: //this does take into account that a product could be a variant of multiple products, but this shouldn't ever really happen...
506: if (productAssocs != null && productAssocs.size() > 0) {
507: Iterator pasIter = productAssocs.iterator();
508: while (pasIter.hasNext()) {
509: GenericValue productAssoc = (GenericValue) pasIter
510: .next();
511: if (isProductInCategory(delegator, productAssoc
512: .getString("productId"), productCategoryId)) {
513: return true;
514: }
515: }
516: }
517:
518: return false;
519: } else {
520: return true;
521: }
522: }
523:
524: public static List filterProductsInCategory(
525: GenericDelegator delegator, List valueObjects,
526: String productCategoryId) throws GenericEntityException {
527: return filterProductsInCategory(delegator, valueObjects,
528: productCategoryId, "productId");
529: }
530:
531: public static List filterProductsInCategory(
532: GenericDelegator delegator, List valueObjects,
533: String productCategoryId, String productIdFieldName)
534: throws GenericEntityException {
535: List newList = FastList.newInstance();
536:
537: if (productCategoryId == null)
538: return newList;
539: if (valueObjects == null)
540: return null;
541:
542: Iterator valIter = valueObjects.iterator();
543: while (valIter.hasNext()) {
544: GenericValue curValue = (GenericValue) valIter.next();
545: String productId = curValue.getString(productIdFieldName);
546: if (isProductInCategory(delegator, productId,
547: productCategoryId)) {
548: newList.add(curValue);
549: }
550: }
551: return newList;
552: }
553:
554: public static void getCategoryContentWrappers(
555: Map catContentWrappers, List categoryList,
556: HttpServletRequest request) throws GenericEntityException {
557: if (catContentWrappers == null || categoryList == null) {
558: return;
559: }
560: Iterator catIterator = categoryList.iterator();
561: while (catIterator.hasNext()) {
562: GenericValue cat = (GenericValue) catIterator.next();
563: String productCategoryId = (String) cat
564: .get("productCategoryId");
565:
566: if (catContentWrappers.containsKey(productCategoryId)) {
567: // if this ID is already in the Map, skip it (avoids inefficiency, infinite recursion, etc.)
568: continue;
569: }
570:
571: CategoryContentWrapper catContentWrapper = new CategoryContentWrapper(
572: cat, request);
573: catContentWrappers
574: .put(productCategoryId, catContentWrapper);
575: List subCat = FastList.newInstance();
576: subCat = getRelatedCategoriesRet(request, "subCatList",
577: productCategoryId, true);
578: if (subCat != null) {
579: getCategoryContentWrappers(catContentWrappers, subCat,
580: request);
581: }
582: }
583: }
584: }
|