public Document prepareDocument()

in lucene/src/main/java/org/apache/ofbiz/content/search/ProductDocument.java [146:370]


    public Document prepareDocument(Delegator delegator) {
        String productId = getDocumentIdentifier().text();
        try {
            GenericValue product = EntityQuery.use(delegator).from("Product").where("productId", productId).queryOne();
            if (product == null) {
                // Return a null document (we will remove the document from the index)
                return null;
            } else {
                if ("Y".equals(product.getString("isVariant")) && "true".equals(EntityUtilProperties.getPropertyValue("prodsearch", "index.ignore"
                        + ".variants", delegator))) {
                    return null;
                }
                Document doc = new Document();
                Timestamp nextReIndex = null;

                // Product Fields
                doc.add(new StringField("productId", productId, Field.Store.YES));
                addTextField(doc, "productName", product.getString("productName"), false, "fullText", delegator);
                addTextField(doc, "internalName", product.getString("internalName"), false, "fullText", delegator);
                addTextField(doc, "brandName", product.getString("brandName"), false, "fullText", delegator);
                addTextField(doc, "description", product.getString("description"), false, "fullText", delegator);
                addTextField(doc, "longDescription", product.getString("longDescription"), false, "fullText", delegator);
                doc.add(new LongPoint("introductionDate", quantizeTimestampToDays(product.getTimestamp("introductionDate"))));
                nextReIndex = checkSetNextReIndex(product.getTimestamp("introductionDate"), nextReIndex);
                doc.add(new LongPoint("salesDiscontinuationDate", quantizeTimestampToDays(product.getTimestamp("salesDiscontinuationDate"))));
                nextReIndex = checkSetNextReIndex(product.getTimestamp("salesDiscontinuationDate"), nextReIndex);
                doc.add(new StringField("isVariant", product.get("isVariant") != null && product.getBoolean("isVariant") ? "true" : "false",
                        Field.Store.NO));

                // ProductFeature Fields, check that at least one of the fields is set to be indexed
                if (!"0".equals(EntityUtilProperties.getPropertyValue("prodsearch", "index.weight.ProductFeatureAndAppl.description", "0", delegator))
                        || !"0".equals(EntityUtilProperties.getPropertyValue("prodsearch", "index.weight.ProductFeatureAndAppl.abbrev", "0",
                        delegator))
                        || !"0".equals(EntityUtilProperties.getPropertyValue("prodsearch", "index.weight.ProductFeatureAndAppl.idCode", "0",
                        delegator))) {

                    List<GenericValue> productFeatureAndAppls = EntityQuery.use(delegator).from("ProductFeatureAndAppl").where("productId",
                            productId).queryList();
                    productFeatureAndAppls = filterByThruDate(productFeatureAndAppls);

                    for (GenericValue productFeatureAndAppl : productFeatureAndAppls) {
                        Timestamp fromDate = productFeatureAndAppl.getTimestamp("fromDate");
                        Timestamp thruDate = productFeatureAndAppl.getTimestamp("thruDate");
                        if (fromDate != null && fromDate.after(UtilDateTime.nowTimestamp())) {
                            // fromDate is after now, update reindex date but don't index the feature
                            nextReIndex = checkSetNextReIndex(fromDate, nextReIndex);
                            continue;
                        } else if (thruDate != null) {
                            nextReIndex = checkSetNextReIndex(thruDate, nextReIndex);
                        }
                        doc.add(new StringField("productFeatureId", productFeatureAndAppl.getString("productFeatureId"), Field.Store.NO));
                        doc.add(new StringField("productFeatureCategoryId", productFeatureAndAppl.getString("productFeatureCategoryId"),
                                Field.Store.NO));
                        doc.add(new StringField("productFeatureTypeId", productFeatureAndAppl.getString("productFeatureTypeId"), Field.Store.NO));
                        addTextField(doc, "featureDescription", productFeatureAndAppl.getString("description"), false, "fullText", delegator);
                        addTextField(doc, "featureAbbreviation", productFeatureAndAppl.getString("abbrev"), false, "fullText", delegator);
                        addTextField(doc, "featureCode", productFeatureAndAppl.getString("idCode"), false, "fullText", delegator);
                        // Get the ProductFeatureGroupIds
                        List<GenericValue> productFeatureGroupAppls = EntityQuery.use(delegator).from("ProductFeatureGroupAppl").where(
                                "productFeatureId", productFeatureAndAppl.get("productFeatureId")).queryList();
                        productFeatureGroupAppls = filterByThruDate(productFeatureGroupAppls);
                        for (GenericValue productFeatureGroupAppl : productFeatureGroupAppls) {
                            fromDate = productFeatureGroupAppl.getTimestamp("fromDate");
                            thruDate = productFeatureGroupAppl.getTimestamp("thruDate");
                            if (fromDate != null && fromDate.after(UtilDateTime.nowTimestamp())) {
                                // fromDate is after now, update reindex date but don't index the feature
                                nextReIndex = checkSetNextReIndex(fromDate, nextReIndex);
                                continue;
                            } else if (thruDate != null) {
                                nextReIndex = checkSetNextReIndex(thruDate, nextReIndex);
                            }
                            doc.add(new StringField("productFeatureGroupId", productFeatureGroupAppl.getString("productFeatureGroupId"),
                                    Field.Store.NO));
                        }
                    }
                }

                // ProductAttribute Fields
                if (!"0".equals(EntityUtilProperties.getPropertyValue("prodsearch", "index.weight.ProductAttribute.attrName", "0", delegator))
                        || !"0".equals(EntityUtilProperties.getPropertyValue("prodsearch", "index.weight.ProductAttribute.attrValue", "0",
                        delegator))) {

                    List<GenericValue> productAttributes =
                            EntityQuery.use(delegator).from("ProductAttribute").where("productId", productId).queryList();
                    for (GenericValue productAttribute : productAttributes) {
                        addTextField(doc, "attributeName", productAttribute.getString("attrName"), false, "fullText", delegator);
                        addTextField(doc, "attributeValue", productAttribute.getString("attrValue"), false, "fullText", delegator);
                    }
                }

                // GoodIdentification
                if (!"0".equals(EntityUtilProperties.getPropertyValue("prodsearch", "index.weight.GoodIdentification.idValue", "0", delegator))) {
                    List<GenericValue> goodIdentifications =
                            EntityQuery.use(delegator).from("GoodIdentification").where("productId", productId).queryList();
                    for (GenericValue goodIdentification : goodIdentifications) {
                        String goodIdentificationTypeId = goodIdentification.getString("goodIdentificationTypeId");
                        String idValue = goodIdentification.getString("idValue");
                        doc.add(new StringField("goodIdentificationTypeId", goodIdentificationTypeId, Field.Store.NO));
                        doc.add(new StringField(goodIdentificationTypeId + "_GoodIdentification", idValue, Field.Store.NO));
                        addTextField(doc, "identificationValue", idValue, false, "fullText", delegator);
                    }
                }

                // Virtual ProductIds
                if ("Y".equals(product.getString("isVirtual"))) {
                    if (!"0".equals(EntityUtilProperties.getPropertyValue("prodsearch", "index.weight.Variant.Product.productId", "0", delegator))) {
                        List<GenericValue> variantProductAssocs = EntityQuery.use(delegator).from("ProductAssoc").where("productId", productId,
                                "productAssocTypeId", "PRODUCT_VARIANT").queryList();
                        variantProductAssocs = filterByThruDate(variantProductAssocs);
                        for (GenericValue variantProductAssoc : variantProductAssocs) {
                            Timestamp fromDate = variantProductAssoc.getTimestamp("fromDate");
                            Timestamp thruDate = variantProductAssoc.getTimestamp("thruDate");
                            if (fromDate != null && fromDate.after(UtilDateTime.nowTimestamp())) {
                                // fromDate is after now, update reindex date but don't index the feature
                                nextReIndex = checkSetNextReIndex(fromDate, nextReIndex);
                                continue;
                            } else if (thruDate != null) {
                                nextReIndex = checkSetNextReIndex(thruDate, nextReIndex);
                            }
                            addTextField(doc, "variantProductId", variantProductAssoc.getString("productIdTo"), false, "fullText", delegator);
                        }
                    }
                }

                // Index product content
                String productContentTypes = EntityUtilProperties.getPropertyValue("prodsearch", "index.include.ProductContentTypes", delegator);
                for (String productContentTypeId : productContentTypes.split(",")) {
                    try {
                        EntityUtilProperties.getPropertyAsInteger("prodsearch", "index.weight.ProductContent." + productContentTypeId, 1);
                    } catch (Exception e) {
                        Debug.logWarning("Could not parse weight number: " + e.toString(), MODULE);
                    }

                    List<GenericValue> productContentAndInfos = EntityQuery.use(delegator).from("ProductContentAndInfo").where("productId",
                            productId, "productContentTypeId", productContentTypeId).queryList();
                    productContentAndInfos = filterByThruDate(productContentAndInfos);
                    for (GenericValue productContentAndInfo : productContentAndInfos) {
                        Timestamp fromDate = productContentAndInfo.getTimestamp("fromDate");
                        Timestamp thruDate = productContentAndInfo.getTimestamp("thruDate");
                        if (fromDate != null && fromDate.after(UtilDateTime.nowTimestamp())) {
                            // fromDate is after now, update reindex date but don't index the feature
                            nextReIndex = checkSetNextReIndex(fromDate, nextReIndex);
                            continue;
                        } else if (thruDate != null) {
                            nextReIndex = checkSetNextReIndex(thruDate, nextReIndex);
                        }
                        try {
                            Map<String, Object> drContext = UtilMisc.<String, Object>toMap("product", product);
                            String contentText = DataResourceWorker.renderDataResourceAsText(null, delegator, productContentAndInfo.getString(
                                    "dataResourceId"), drContext, null, null, false);
                            addTextField(doc, "content", contentText, false, "fullText", delegator);
                        } catch (IOException | GeneralException e1) {
                            Debug.logError(e1, "Error getting content text to index", MODULE);
                        }

                        // TODO: Not indexing alternate locales, needs special handling
                        /*
                        List<GenericValue> alternateViews = productContentAndInfo.getRelated("ContentAssocDataResourceViewTo", UtilMisc.toMap
                        ("caContentAssocTypeId", "ALTERNATE_LOCALE"), UtilMisc.toList("-caFromDate"));
                        alternateViews = EntityUtil.filterByDate(alternateViews, UtilDateTime.nowTimestamp(), "caFromDate", "caThruDate", true);
                        for (GenericValue thisView: alternateViews) {
                        }
                        */
                    }
                }

                // Index the product's directProductCategoryIds (direct parents), productCategoryIds (all ancestors) and prodCatalogIds
                this.populateCategoryData(doc, product);

                // Index ProductPrices, uses dynamic fields in the format
                // ${productPriceTypeId}_${productPricePurposeId}_${currencyUomId}_${productStoreGroupId}_price
                List<GenericValue> productPrices = product.getRelated("ProductPrice", null, null, false);
                productPrices = filterByThruDate(productPrices);
                for (GenericValue productPrice : productPrices) {
                    Timestamp fromDate = productPrice.getTimestamp("fromDate");
                    Timestamp thruDate = productPrice.getTimestamp("thruDate");
                    if (fromDate != null && fromDate.after(UtilDateTime.nowTimestamp())) {
                        // fromDate is after now, update reindex date but don't index the feature
                        nextReIndex = checkSetNextReIndex(fromDate, nextReIndex);
                        continue;
                    } else if (thruDate != null) {
                        nextReIndex = checkSetNextReIndex(thruDate, nextReIndex);
                    }
                    StringBuilder fieldNameSb = new StringBuilder();
                    fieldNameSb.append(productPrice.getString("productPriceTypeId"));
                    fieldNameSb.append('_');
                    fieldNameSb.append(productPrice.getString("productPricePurposeId"));
                    fieldNameSb.append('_');
                    fieldNameSb.append(productPrice.getString("currencyUomId"));
                    fieldNameSb.append('_');
                    fieldNameSb.append(productPrice.getString("productStoreGroupId"));
                    fieldNameSb.append("_price");
                    doc.add(new DoublePoint(fieldNameSb.toString(), productPrice.getDouble("price")));
                }

                // Index ProductSuppliers
                List<GenericValue> supplierProducts = product.getRelated("SupplierProduct", null, null, false);
                supplierProducts = filterByThruDate(supplierProducts, "availableThruDate");
                Set<String> supplierPartyIds = new TreeSet<>();
                for (GenericValue supplierProduct : supplierProducts) {
                    Timestamp fromDate = supplierProduct.getTimestamp("availableFromDate");
                    Timestamp thruDate = supplierProduct.getTimestamp("availableThruDate");
                    if (fromDate != null && fromDate.after(UtilDateTime.nowTimestamp())) {
                        // fromDate is after now, update reindex date but don't index the feature
                        nextReIndex = checkSetNextReIndex(fromDate, nextReIndex);
                        continue;
                    } else if (thruDate != null) {
                        nextReIndex = checkSetNextReIndex(thruDate, nextReIndex);
                    }
                    supplierPartyIds.add(supplierProduct.getString("partyId"));
                }
                for (String supplierPartyId : supplierPartyIds) {
                    doc.add(new StringField("supplierPartyId", supplierPartyId, Field.Store.NO));
                }

                // TODO: Add the nextReIndex timestamp to the document for when the product should be automatically re-indexed outside of any ECAs
                // based on the next known from/thru date whose passing will cause a change to the document.  Need to build a scheduled service to
                // look for these.
                return doc;
            }
        } catch (GenericEntityException e) {
            Debug.logError(e, MODULE);
        }
        return null;
    }