This is an automated email from the ASF dual-hosted git repository. mbrohl pushed a commit to branch trunk in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git
The following commit(s) were added to refs/heads/trunk by this push: new a41f0540ba Improved: ContentWrapper empty string result breaks simple FTL null check and default syntax (OFBIZ-10194) a41f0540ba is described below commit a41f0540ba3c7f99a1deb1d2d1efb55510cd19e1 Author: Adrian Wolf <adrian.w...@ecomify.de> AuthorDate: Fri Apr 21 14:08:14 2023 +0200 Improved: ContentWrapper empty string result breaks simple FTL null check and default syntax (OFBIZ-10194) --- .../ofbiz/content/content/ContentWrapper.java | 85 +++++++++++++ .../ofbiz/order/order/OrderContentWrapper.java | 51 ++++---- .../ofbiz/party/content/PartyContentWrapper.java | 132 +++++++++------------ .../product/category/CategoryContentWrapper.java | 113 +++++++++--------- .../config/ProductConfigItemContentWrapper.java | 94 ++++++++------- .../product/product/ProductContentWrapper.java | 129 +++++++++----------- .../product/ProductPromoContentWrapper.java | 80 ++++++------- 7 files changed, 375 insertions(+), 309 deletions(-) diff --git a/applications/content/src/main/java/org/apache/ofbiz/content/content/ContentWrapper.java b/applications/content/src/main/java/org/apache/ofbiz/content/content/ContentWrapper.java index 15115c90e1..5a0db6df11 100644 --- a/applications/content/src/main/java/org/apache/ofbiz/content/content/ContentWrapper.java +++ b/applications/content/src/main/java/org/apache/ofbiz/content/content/ContentWrapper.java @@ -18,7 +18,18 @@ *******************************************************************************/ package org.apache.ofbiz.content.content; +import org.apache.ofbiz.base.util.Debug; import org.apache.ofbiz.base.util.StringUtil; +import org.apache.ofbiz.base.util.UtilCodec; +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.condition.EntityCondition; +import org.apache.ofbiz.entity.model.ModelEntity; +import org.apache.ofbiz.entity.model.ModelUtil; +import org.apache.ofbiz.entity.util.EntityQuery; +import org.apache.ofbiz.entity.util.EntityUtilProperties; /** * ContentWrapper Interface @@ -26,6 +37,80 @@ import org.apache.ofbiz.base.util.StringUtil; public interface ContentWrapper { + String MDOULE = ContentWrapper.class.getName(); + StringUtil.StringWrapper get(String contentTypeId, String encoderType); + /** + * Get the configured default for content mimeTypeId. + * @param delegator + * @return + */ + static String getDefaultMimeTypeId(Delegator delegator) { + return EntityUtilProperties.getPropertyValue("content", "defaultMimeType", "text/html; charset=utf-8", delegator); + } + + /** + * Check modelObject for existance of a field named like given contentTypeId and + * return its value as String. + * @param modelObject + * @param contentTypeId + * @return + */ + static String getCandidateFieldValue(GenericValue modelObject, String contentTypeId) { + if (modelObject != null) { + String candidateFieldName = ModelUtil.dbNameToVarName(contentTypeId); + if (modelObject.getModelEntity().isField(candidateFieldName)) { + return modelObject.getString(candidateFieldName); + } + } + return null; + } + + /** + * Check if modelEntityName is an existing entity and has a field named like + * given contentTypeId and get the unique modelObject entry by modelObjectPk and + * return the candidate field value as String. + * @param delegator + * @param modelEntityName + * @param modelObjectPk + * @param contentTypeId + * @param useCache + * @return + * @throws GenericEntityException + */ + static String getCandidateFieldValue(Delegator delegator, String modelEntityName, EntityCondition modelObjectPk, + String contentTypeId, boolean useCache) throws GenericEntityException { + + ModelEntity modelEntity = delegator.getModelEntity(modelEntityName); + if (modelEntity != null) { + String candidateFieldName = ModelUtil.dbNameToVarName(contentTypeId); + + if (modelEntity.isField(candidateFieldName)) { + GenericValue modelObject = EntityQuery.use(delegator).from(modelEntityName).where(modelObjectPk).cache(useCache).queryOne(); + if (modelObject != null) { + return modelObject.getString(candidateFieldName); + } + } + } + return null; + } + + /** + * Encode given content string via given encoderType. + * @param value + * @param encoderType + * @return + */ + static String encodeContentValue(String value, String encoderType) { + if (UtilValidate.isNotEmpty(value)) { + UtilCodec.SimpleEncoder encoder = UtilCodec.getEncoder(encoderType); + if (encoder != null) { + value = encoder.sanitize(value, null); + } else { + Debug.logWarning("Unknown encoderType %s for encoding content value!", MDOULE, encoderType); + } + } + return value; + } } diff --git a/applications/order/src/main/java/org/apache/ofbiz/order/order/OrderContentWrapper.java b/applications/order/src/main/java/org/apache/ofbiz/order/order/OrderContentWrapper.java index fb36697642..06e7ae347c 100644 --- a/applications/order/src/main/java/org/apache/ofbiz/order/order/OrderContentWrapper.java +++ b/applications/order/src/main/java/org/apache/ofbiz/order/order/OrderContentWrapper.java @@ -30,7 +30,6 @@ import javax.servlet.http.HttpServletRequest; import org.apache.ofbiz.base.util.Debug; import org.apache.ofbiz.base.util.GeneralException; import org.apache.ofbiz.base.util.StringUtil; -import org.apache.ofbiz.base.util.UtilCodec; import org.apache.ofbiz.base.util.UtilHttp; import org.apache.ofbiz.base.util.UtilValidate; import org.apache.ofbiz.base.util.cache.UtilCache; @@ -51,8 +50,8 @@ public class OrderContentWrapper implements ContentWrapper { private static final String MODULE = OrderContentWrapper.class.getName(); private static final String SEPARATOR = "::"; // cache key separator - private static final UtilCache<String, String> ORDER_CONTENT_CACHE = UtilCache.createUtilCache("order.content", true); - // use soft reference to free up memory if needed + private static final UtilCache<String, String> ORDER_CONTENT_CACHE = UtilCache.createUtilCache( + "order.content.rendered", true); // use soft reference to free up memory if needed public static OrderContentWrapper makeOrderContentWrapper(GenericValue order, HttpServletRequest request) { return new OrderContentWrapper(order, request); @@ -74,8 +73,7 @@ public class OrderContentWrapper implements ContentWrapper { this.dispatcher = (LocalDispatcher) request.getAttribute("dispatcher"); this.order = order; this.locale = UtilHttp.getLocale(request); - this.mimeTypeId = EntityUtilProperties.getPropertyValue("content", "defaultMimeType", "text/html; charset=utf-8", - (Delegator) request.getAttribute("delegator")); + this.mimeTypeId = ContentWrapper.getDefaultMimeTypeId((Delegator) request.getAttribute("delegator")); } @Override @@ -86,7 +84,7 @@ public class OrderContentWrapper implements ContentWrapper { public static String getOrderContentAsText(GenericValue order, String orderContentTypeId, HttpServletRequest request, String encoderType) { LocalDispatcher dispatcher = (LocalDispatcher) request.getAttribute("dispatcher"); - String mimeTypeId = EntityUtilProperties.getPropertyValue("content", "defaultMimeType", "text/html; charset=utf-8", order.getDelegator()); + String mimeTypeId = ContentWrapper.getDefaultMimeTypeId(order.getDelegator()); return getOrderContentAsText(order, orderContentTypeId, UtilHttp.getLocale(request), mimeTypeId, order.getDelegator(), dispatcher, encoderType); } @@ -98,32 +96,40 @@ public class OrderContentWrapper implements ContentWrapper { public static String getOrderContentAsText(GenericValue order, String orderContentTypeId, Locale locale, String mimeTypeId, Delegator delegator, LocalDispatcher dispatcher, String encoderType) { + if (order == null) { + return null; + } + String orderItemSeqId = ("OrderItem".equals(order.getEntityName()) ? order.getString("orderItemSeqId") + : "_NA_"); + + /* Look for a previously cached entry (may also be an entry with null value if + * there was no content to retrieve) + */ /* caching: there is one cache created, "order.content" Each order's content is cached with a key of * contentTypeId::locale::mimeType::orderId::orderItemSeqId, or whatever the SEPARATOR is defined above to be. */ - UtilCodec.SimpleEncoder encoder = UtilCodec.getEncoder(encoderType); - String orderItemSeqId = ("OrderItem".equals(order.getEntityName()) ? order.getString("orderItemSeqId") : "_NA_"); + String cacheKey = orderContentTypeId + SEPARATOR + locale + SEPARATOR + mimeTypeId + SEPARATOR + order.get( + "orderId") + SEPARATOR + orderItemSeqId + SEPARATOR + encoderType + SEPARATOR + delegator; + String cachedValue = ORDER_CONTENT_CACHE.get(cacheKey); + if (cachedValue != null || ORDER_CONTENT_CACHE.containsKey(cacheKey)) { + return cachedValue; + } + + // Get content of given contentTypeId + String outString = null; - String cacheKey = orderContentTypeId + SEPARATOR + locale + SEPARATOR + mimeTypeId + SEPARATOR + order.get("orderId") + SEPARATOR - + orderItemSeqId + SEPARATOR + encoderType + SEPARATOR + delegator; try { - String cachedValue = ORDER_CONTENT_CACHE.get(cacheKey); - if (cachedValue != null) { - return cachedValue; - } - Writer outWriter = new StringWriter(); - getOrderContentAsText(null, null, order, orderContentTypeId, locale, mimeTypeId, delegator, dispatcher, outWriter, false); - String outString = outWriter.toString(); - outString = encoder.sanitize(outString, null); + getOrderContentAsText(null, orderItemSeqId, order, orderContentTypeId, locale, mimeTypeId, delegator, + dispatcher, outWriter, false); + // Encode found content via given encoderType + outString = ContentWrapper.encodeContentValue(outWriter.toString(), encoderType); ORDER_CONTENT_CACHE.put(cacheKey, outString); - return outString; - } catch (GeneralException | IOException e) { - Debug.logError(e, "Error rendering OrderContent, inserting empty String", MODULE); - return ""; + Debug.logError(e, "Error rendering OrderContent", MODULE); } + return outString; } public static void getOrderContentAsText(String orderId, String orderItemSeqId, GenericValue order, String orderContentTypeId, Locale locale, @@ -165,4 +171,3 @@ public class OrderContentWrapper implements ContentWrapper { } } } - diff --git a/applications/party/src/main/java/org/apache/ofbiz/party/content/PartyContentWrapper.java b/applications/party/src/main/java/org/apache/ofbiz/party/content/PartyContentWrapper.java index 4d43003f29..6a6c526b61 100644 --- a/applications/party/src/main/java/org/apache/ofbiz/party/content/PartyContentWrapper.java +++ b/applications/party/src/main/java/org/apache/ofbiz/party/content/PartyContentWrapper.java @@ -34,7 +34,6 @@ import org.apache.ofbiz.base.util.Debug; import org.apache.ofbiz.base.util.GeneralException; import org.apache.ofbiz.base.util.GeneralRuntimeException; import org.apache.ofbiz.base.util.StringUtil; -import org.apache.ofbiz.base.util.UtilCodec; import org.apache.ofbiz.base.util.UtilHttp; import org.apache.ofbiz.base.util.UtilValidate; import org.apache.ofbiz.base.util.cache.UtilCache; @@ -42,11 +41,9 @@ import org.apache.ofbiz.content.content.ContentWorker; import org.apache.ofbiz.content.content.ContentWrapper; import org.apache.ofbiz.entity.Delegator; import org.apache.ofbiz.entity.GenericValue; -import org.apache.ofbiz.entity.model.ModelEntity; -import org.apache.ofbiz.entity.model.ModelUtil; +import org.apache.ofbiz.entity.condition.EntityCondition; import org.apache.ofbiz.entity.util.EntityQuery; import org.apache.ofbiz.entity.util.EntityUtil; -import org.apache.ofbiz.entity.util.EntityUtilProperties; import org.apache.ofbiz.service.LocalDispatcher; /** @@ -75,8 +72,7 @@ public class PartyContentWrapper implements ContentWrapper { this.dispatcher = (LocalDispatcher) request.getAttribute("dispatcher"); this.party = party; this.locale = UtilHttp.getLocale(request); - this.mimeTypeId = EntityUtilProperties.getPropertyValue("content", "defaultMimeType", "text/html; charset=utf-8", - (Delegator) request.getAttribute("delegator")); + this.mimeTypeId = ContentWrapper.getDefaultMimeTypeId(party.getDelegator()); } /** @@ -147,7 +143,7 @@ public class PartyContentWrapper implements ContentWrapper { // static methods public static String getPartyContentAsText(GenericValue party, String partyContentId, HttpServletRequest request, String encoderType) { LocalDispatcher dispatcher = (LocalDispatcher) request.getAttribute("dispatcher"); - String mimeTypeId = EntityUtilProperties.getPropertyValue("content", "defaultMimeType", "text/html; charset=utf-8", party.getDelegator()); + String mimeTypeId = ContentWrapper.getDefaultMimeTypeId(party.getDelegator()); return getPartyContentAsText(party, partyContentId, null, UtilHttp.getLocale(request), mimeTypeId, party.getDelegator(), dispatcher, true, encoderType); } @@ -168,44 +164,47 @@ public class PartyContentWrapper implements ContentWrapper { return null; } - UtilCodec.SimpleEncoder encoder = UtilCodec.getEncoder(encoderType); - String candidateFieldName = ModelUtil.dbNameToVarName(partyContentTypeId); - String cacheKey; - if (contentId != null) { - cacheKey = contentId + CACHE_KEY_SEPARATOR + locale + CACHE_KEY_SEPARATOR + mimeTypeId - + CACHE_KEY_SEPARATOR + party.get("partyId"); - } else { - cacheKey = partyContentTypeId + CACHE_KEY_SEPARATOR + locale + CACHE_KEY_SEPARATOR + mimeTypeId - + CACHE_KEY_SEPARATOR + party.get("partyId"); - } + String cacheKey = null; + if (useCache) { + if (contentId != null) { + cacheKey = contentId + CACHE_KEY_SEPARATOR + locale + CACHE_KEY_SEPARATOR + mimeTypeId + + CACHE_KEY_SEPARATOR + party.get("partyId"); + } else { + cacheKey = partyContentTypeId + CACHE_KEY_SEPARATOR + locale + CACHE_KEY_SEPARATOR + mimeTypeId + + CACHE_KEY_SEPARATOR + party.get("partyId"); + } - try { - if (useCache) { - String cachedValue = PARTY_CONTENT_CACHE.get(cacheKey); - if (cachedValue != null) { - return cachedValue; - } + String cachedValue = PARTY_CONTENT_CACHE.get(cacheKey); + if (cachedValue != null || PARTY_CONTENT_CACHE.containsKey(cacheKey)) { + return cachedValue; } + } + // Get content of given contentTypeId + String outString = null; + try { Writer outWriter = new StringWriter(); - getPartyContentAsText(contentId, party.getString("partyId"), party, partyContentTypeId, locale, mimeTypeId, delegator, dispatcher, - outWriter, false); - - String outString = outWriter.toString(); - if (UtilValidate.isEmpty(outString)) { - outString = party.getModelEntity().isField(candidateFieldName) ? party.getString(candidateFieldName) : ""; - outString = outString == null ? "" : outString; - } - outString = encoder.sanitize(outString, null); - if (PARTY_CONTENT_CACHE != null) { - PARTY_CONTENT_CACHE.put(cacheKey, outString); - } - return outString; + getPartyContentAsText(contentId, party.getString("partyId"), party, partyContentTypeId, locale, mimeTypeId, + delegator, dispatcher, outWriter, false); + outString = outWriter.toString(); } catch (GeneralException | IOException e) { - Debug.logError(e, "Error rendering PartyContent, inserting empty String", MODULE); - String candidateOut = party.getModelEntity().isField(candidateFieldName) ? party.getString(candidateFieldName) : ""; - return candidateOut == null ? "" : encoder.sanitize(candidateOut, null); + Debug.logError(e, "Error rendering PartyContent", MODULE); + useCache = false; } + + /* If we did not found any content (or got an error), get the content of a + * candidateFieldName matching the given contentTypeId + */ + if (UtilValidate.isEmpty(outString)) { + outString = ContentWrapper.getCandidateFieldValue(party, partyContentTypeId); + } + // Encode found content via given encoderType + outString = ContentWrapper.encodeContentValue(outString, encoderType); + + if (useCache) { + PARTY_CONTENT_CACHE.put(cacheKey, outString); + } + return outString; } public static void getPartyContentAsText(String contentId, String partyId, GenericValue party, String partyContentTypeId, Locale locale, @@ -223,15 +222,14 @@ public class PartyContentWrapper implements ContentWrapper { if (delegator == null && party != null) { delegator = party.getDelegator(); } - - if (UtilValidate.isEmpty(mimeTypeId)) { - mimeTypeId = EntityUtilProperties.getPropertyValue("content", "defaultMimeType", "text/html; charset=utf-8", delegator); - } - if (delegator == null) { throw new GeneralRuntimeException("Unable to find a delegator to use!"); } + if (UtilValidate.isEmpty(mimeTypeId)) { + mimeTypeId = ContentWrapper.getDefaultMimeTypeId(delegator); + } + // Honor party content over Party entity fields. GenericValue partyContent; if (contentId != null) { @@ -240,46 +238,26 @@ public class PartyContentWrapper implements ContentWrapper { partyContent = getFirstPartyContentByType(partyId, party, partyContentTypeId, delegator); } if (partyContent != null) { - // when rendering the product content, always include the Product and ProductContent records that this comes from + /* when rendering the party content, always include the Party and PartyContent + * records that this comes from + */ Map<String, Object> inContext = new HashMap<>(); inContext.put("party", party); inContext.put("partyContent", partyContent); ContentWorker.renderContentAsText(dispatcher, partyContent.getString("contentId"), outWriter, inContext, locale, mimeTypeId, null, null, cache); - return; - } - - if (partyContentTypeId != null) { - String candidateFieldName = ModelUtil.dbNameToVarName(partyContentTypeId); - + // check person and group entity fields, if no content was found + } else if (partyContentTypeId != null) { // first check for a person field - ModelEntity partyPersonModel = delegator.getModelEntity("PartyAndPerson"); - if (partyPersonModel != null && partyPersonModel.isField(candidateFieldName)) { - if (party == null) { - party = EntityQuery.use(delegator).from("PartyAndPerson").where("partyId", partyId).cache().queryOne(); - } - if (party != null) { - String candidateValue = party.getString(candidateFieldName); - if (UtilValidate.isNotEmpty(candidateValue)) { - outWriter.write(candidateValue); - return; - } - } + String candidateValue = ContentWrapper.getCandidateFieldValue(delegator, "PartyAndPerson", EntityCondition + .makeCondition("partyId", partyId), partyContentTypeId, cache); + if (UtilValidate.isEmpty(candidateValue)) { + // next check for group field + candidateValue = ContentWrapper.getCandidateFieldValue(delegator, "PartyAndGroup", EntityCondition + .makeCondition("partyId", partyId), partyContentTypeId, cache); } - - // next check for group field - ModelEntity partyGroupModel = delegator.getModelEntity("PartyAndGroup"); - if (partyGroupModel != null && partyGroupModel.isField(candidateFieldName)) { - if (party == null) { - party = EntityQuery.use(delegator).from("PartyAndGroup").where("partyId", partyId).cache().queryOne(); - } - if (party != null) { - String candidateValue = party.getString(candidateFieldName); - if (UtilValidate.isNotEmpty(candidateValue)) { - outWriter.write(candidateValue); - return; - } - } + if (UtilValidate.isNotEmpty(candidateValue)) { + outWriter.write(candidateValue); } } } diff --git a/applications/product/src/main/java/org/apache/ofbiz/product/category/CategoryContentWrapper.java b/applications/product/src/main/java/org/apache/ofbiz/product/category/CategoryContentWrapper.java index 3e35ac68da..a4d05c6bbf 100644 --- a/applications/product/src/main/java/org/apache/ofbiz/product/category/CategoryContentWrapper.java +++ b/applications/product/src/main/java/org/apache/ofbiz/product/category/CategoryContentWrapper.java @@ -30,9 +30,7 @@ import javax.servlet.http.HttpServletRequest; import org.apache.ofbiz.base.util.Debug; import org.apache.ofbiz.base.util.GeneralException; -import org.apache.ofbiz.base.util.GeneralRuntimeException; import org.apache.ofbiz.base.util.StringUtil; -import org.apache.ofbiz.base.util.UtilCodec; import org.apache.ofbiz.base.util.UtilHttp; import org.apache.ofbiz.base.util.UtilValidate; import org.apache.ofbiz.base.util.cache.UtilCache; @@ -40,11 +38,8 @@ import org.apache.ofbiz.content.content.ContentWorker; import org.apache.ofbiz.content.content.ContentWrapper; import org.apache.ofbiz.entity.Delegator; import org.apache.ofbiz.entity.GenericValue; -import org.apache.ofbiz.entity.model.ModelEntity; -import org.apache.ofbiz.entity.model.ModelUtil; import org.apache.ofbiz.entity.util.EntityQuery; import org.apache.ofbiz.entity.util.EntityUtil; -import org.apache.ofbiz.entity.util.EntityUtilProperties; import org.apache.ofbiz.service.LocalDispatcher; /** @@ -54,8 +49,8 @@ public class CategoryContentWrapper implements ContentWrapper { private static final String MODULE = CategoryContentWrapper.class.getName(); public static final String SEPARATOR = "::"; // cache key separator - private static final UtilCache<String, String> CATEGORY_CONTENT_CACHE = UtilCache.createUtilCache("category.content", true); - // use soft reference to free up memory if needed + private static final UtilCache<String, String> CATEGORY_CONTENT_CACHE = UtilCache.createUtilCache( + "category.content.rendered", true); // use soft reference to free up memory if needed private LocalDispatcher dispatcher; private GenericValue productCategory; @@ -77,8 +72,7 @@ public class CategoryContentWrapper implements ContentWrapper { this.dispatcher = (LocalDispatcher) request.getAttribute("dispatcher"); this.productCategory = productCategory; this.locale = UtilHttp.getLocale(request); - this.mimeTypeId = EntityUtilProperties.getPropertyValue("content", "defaultMimeType", "text/html; charset=utf-8", - (Delegator) request.getAttribute("delegator")); + this.mimeTypeId = ContentWrapper.getDefaultMimeTypeId((Delegator) request.getAttribute("delegator")); } @Override @@ -90,8 +84,7 @@ public class CategoryContentWrapper implements ContentWrapper { public static String getProductCategoryContentAsText(GenericValue productCategory, String prodCatContentTypeId, HttpServletRequest request, String encoderType) { LocalDispatcher dispatcher = (LocalDispatcher) request.getAttribute("dispatcher"); - String mimeTypeId = EntityUtilProperties.getPropertyValue("content", "defaultMimeType", "text/html; charset=utf-8", - productCategory.getDelegator()); + String mimeTypeId = ContentWrapper.getDefaultMimeTypeId(productCategory.getDelegator()); return getProductCategoryContentAsText(productCategory, prodCatContentTypeId, UtilHttp.getLocale(request), mimeTypeId, productCategory.getDelegator(), dispatcher, encoderType); } @@ -101,56 +94,79 @@ public class CategoryContentWrapper implements ContentWrapper { return getProductCategoryContentAsText(productCategory, prodCatContentTypeId, locale, null, null, dispatcher, encoderType); } - public static String getProductCategoryContentAsText(GenericValue productCategory, String prodCatContentTypeId, Locale locale, String mimeTypeId, - Delegator delegator, LocalDispatcher dispatcher, String encoderType) { - String candidateFieldName = ModelUtil.dbNameToVarName(prodCatContentTypeId); - UtilCodec.SimpleEncoder encoder = UtilCodec.getEncoder(encoderType); - String cacheKey = prodCatContentTypeId + SEPARATOR + locale + SEPARATOR + mimeTypeId + SEPARATOR + productCategory.get("productCategoryId") + public static String getProductCategoryContentAsText(GenericValue productCategory, String prodCatContentTypeId, + Locale locale, String mimeTypeId, + Delegator delegator, LocalDispatcher dispatcher, String encoderType) { + if (productCategory == null) { + return null; + } + + /* + * Look for a previously cached entry (may also be an entry with null value if + * there was no content to retrieve) + */ + String cacheKey = prodCatContentTypeId + SEPARATOR + locale + SEPARATOR + mimeTypeId + SEPARATOR + + productCategory.get("productCategoryId") + SEPARATOR + encoderType + SEPARATOR + delegator; + String cachedValue = CATEGORY_CONTENT_CACHE.get(cacheKey); + if (cachedValue != null || CATEGORY_CONTENT_CACHE.containsKey(cacheKey)) { + return cachedValue; + } + + // Get content of given contentTypeId + boolean doCache = true; + String outString = null; try { - String cachedValue = CATEGORY_CONTENT_CACHE.get(cacheKey); - if (cachedValue != null) { - return cachedValue; - } Writer outWriter = new StringWriter(); - getProductCategoryContentAsText(null, productCategory, prodCatContentTypeId, locale, mimeTypeId, delegator, dispatcher, outWriter, false); - String outString = outWriter.toString(); - if (UtilValidate.isEmpty(outString)) { - outString = productCategory.getModelEntity().isField(candidateFieldName) ? productCategory.getString(candidateFieldName) : ""; - outString = outString == null ? "" : outString; - } - outString = encoder.sanitize(outString, null); - CATEGORY_CONTENT_CACHE.put(cacheKey, outString); - return outString; + getProductCategoryContentAsText(null, productCategory, prodCatContentTypeId, locale, mimeTypeId, delegator, + dispatcher, outWriter, false); + outString = outWriter.toString(); } catch (GeneralException | IOException e) { - Debug.logError(e, "Error rendering CategoryContent, inserting empty String", MODULE); - return productCategory.getString(candidateFieldName); + Debug.logError(e, "Error rendering CategoryContent", MODULE); + doCache = false; } + + /* + * If we did not found any content (or got an error), get the content of a + * candidateFieldName matching the given contentTypeId + */ + if (UtilValidate.isEmpty(outString)) { + outString = ContentWrapper.getCandidateFieldValue(productCategory, prodCatContentTypeId); + } + // Encode found content via given encoderType + outString = ContentWrapper.encodeContentValue(outString, encoderType); + + if (doCache) { + CATEGORY_CONTENT_CACHE.put(cacheKey, outString); + } + return outString; } public static void getProductCategoryContentAsText(String productCategoryId, GenericValue productCategory, String prodCatContentTypeId, Locale locale, String mimeTypeId, Delegator delegator, LocalDispatcher dispatcher, Writer outWriter) throws GeneralException, IOException { - getProductCategoryContentAsText(null, productCategory, prodCatContentTypeId, locale, mimeTypeId, delegator, dispatcher, outWriter, true); + getProductCategoryContentAsText(productCategoryId, productCategory, prodCatContentTypeId, locale, mimeTypeId, + delegator, dispatcher, outWriter, true); } public static void getProductCategoryContentAsText(String productCategoryId, GenericValue productCategory, String prodCatContentTypeId, Locale locale, String mimeTypeId, Delegator delegator, LocalDispatcher dispatcher, Writer outWriter, boolean cache) throws GeneralException, IOException { - if (productCategoryId == null && productCategory != null) { + if (productCategory != null) { productCategoryId = productCategory.getString("productCategoryId"); + } else if (productCategoryId != null) { + productCategory = EntityQuery.use(delegator).from("ProductCategory").where("productCategoryId", + productCategoryId).cache(cache).queryOne(); + } else { + throw new GeneralException("Missing parameter productCategory or productCategoryId!"); } - if (delegator == null && productCategory != null) { + if (delegator == null) { delegator = productCategory.getDelegator(); } if (UtilValidate.isEmpty(mimeTypeId)) { - mimeTypeId = EntityUtilProperties.getPropertyValue("content", "defaultMimeType", "text/html; charset=utf-8", delegator); - } - - if (delegator == null) { - throw new GeneralRuntimeException("Unable to find a delegator to use!"); + mimeTypeId = ContentWrapper.getDefaultMimeTypeId(delegator); } List<GenericValue> categoryContentList = EntityQuery.use(delegator).from("ProductCategoryContent").where("productCategoryId", @@ -163,21 +179,10 @@ public class CategoryContentWrapper implements ContentWrapper { inContext.put("categoryContent", categoryContent); ContentWorker.renderContentAsText(dispatcher, categoryContent.getString("contentId"), outWriter, inContext, locale, mimeTypeId, null, null, cache); - return; - } - - String candidateFieldName = ModelUtil.dbNameToVarName(prodCatContentTypeId); - ModelEntity categoryModel = delegator.getModelEntity("ProductCategory"); - if (categoryModel.isField(candidateFieldName)) { - if (productCategory == null) { - productCategory = EntityQuery.use(delegator).from("ProductCategory").where("productCategoryId", productCategoryId).cache().queryOne(); - } - if (productCategory != null) { - String candidateValue = productCategory.getString(candidateFieldName); - if (UtilValidate.isNotEmpty(candidateValue)) { - outWriter.write(candidateValue); - return; - } + } else { + String candidateValue = ContentWrapper.getCandidateFieldValue(productCategory, prodCatContentTypeId); + if (UtilValidate.isNotEmpty(candidateValue)) { + outWriter.write(candidateValue); } } } diff --git a/applications/product/src/main/java/org/apache/ofbiz/product/config/ProductConfigItemContentWrapper.java b/applications/product/src/main/java/org/apache/ofbiz/product/config/ProductConfigItemContentWrapper.java index f5b8f45873..08c97d947b 100644 --- a/applications/product/src/main/java/org/apache/ofbiz/product/config/ProductConfigItemContentWrapper.java +++ b/applications/product/src/main/java/org/apache/ofbiz/product/config/ProductConfigItemContentWrapper.java @@ -31,7 +31,6 @@ import org.apache.ofbiz.base.util.Debug; import org.apache.ofbiz.base.util.GeneralException; import org.apache.ofbiz.base.util.StringUtil; import org.apache.ofbiz.base.util.StringUtil.StringWrapper; -import org.apache.ofbiz.base.util.UtilCodec; import org.apache.ofbiz.base.util.UtilHttp; import org.apache.ofbiz.base.util.UtilValidate; import org.apache.ofbiz.base.util.cache.UtilCache; @@ -40,10 +39,8 @@ import org.apache.ofbiz.content.content.ContentWrapper; import org.apache.ofbiz.entity.Delegator; import org.apache.ofbiz.entity.DelegatorFactory; import org.apache.ofbiz.entity.GenericValue; -import org.apache.ofbiz.entity.model.ModelEntity; -import org.apache.ofbiz.entity.model.ModelUtil; +import org.apache.ofbiz.entity.condition.EntityCondition; import org.apache.ofbiz.entity.util.EntityQuery; -import org.apache.ofbiz.entity.util.EntityUtilProperties; import org.apache.ofbiz.service.LocalDispatcher; import org.apache.ofbiz.service.ServiceContainer; @@ -54,8 +51,8 @@ public class ProductConfigItemContentWrapper implements ContentWrapper { private static final String MODULE = ProductConfigItemContentWrapper.class.getName(); public static final String SEPARATOR = "::"; // cache key separator - private static final UtilCache<String, String> CONFIG_ITEM_CONTENT_CACHE = UtilCache.createUtilCache("configItem.content", true); - // use soft reference to free up memory if needed + private static final UtilCache<String, String> CONFIG_ITEM_CONTENT_CACHE = UtilCache.createUtilCache( + "configItem.content.rendered", true); // use soft reference to free up memory if needed private transient LocalDispatcher dispatcher; private String dispatcherName; @@ -87,7 +84,7 @@ public class ProductConfigItemContentWrapper implements ContentWrapper { this.delegatorName = delegator.getDelegatorName(); this.productConfigItem = productConfigItem; this.locale = UtilHttp.getLocale(request); - this.mimeTypeId = EntityUtilProperties.getPropertyValue("content", "defaultMimeType", "text/html; charset=utf-8", this.delegator); + this.mimeTypeId = ContentWrapper.getDefaultMimeTypeId(this.delegator); } @Override @@ -121,8 +118,7 @@ public class ProductConfigItemContentWrapper implements ContentWrapper { public static String getProductConfigItemContentAsText(GenericValue productConfigItem, String confItemContentTypeId, HttpServletRequest request, String encoderType) { LocalDispatcher dispatcher = (LocalDispatcher) request.getAttribute("dispatcher"); - String mimeTypeId = EntityUtilProperties.getPropertyValue("content", "defaultMimeType", "text/html; charset=utf-8", - productConfigItem.getDelegator()); + String mimeTypeId = ContentWrapper.getDefaultMimeTypeId(productConfigItem.getDelegator()); return getProductConfigItemContentAsText(productConfigItem, confItemContentTypeId, UtilHttp.getLocale(request), mimeTypeId, productConfigItem.getDelegator(), dispatcher, encoderType); } @@ -134,32 +130,46 @@ public class ProductConfigItemContentWrapper implements ContentWrapper { public static String getProductConfigItemContentAsText(GenericValue productConfigItem, String confItemContentTypeId, Locale locale, String mimeTypeId, Delegator delegator, LocalDispatcher dispatcher, String encoderType) { - UtilCodec.SimpleEncoder encoder = UtilCodec.getEncoder(encoderType); - String candidateFieldName = ModelUtil.dbNameToVarName(confItemContentTypeId); - String cacheKey = confItemContentTypeId + SEPARATOR + locale + SEPARATOR + mimeTypeId + SEPARATOR + productConfigItem.get("configItemId") - + SEPARATOR + encoderType + SEPARATOR + delegator; + if (productConfigItem == null) { + return null; + } + /* Look for a previously cached entry (may also be an entry with null value if + * there was no content to retrieve) + */ + String cacheKey = confItemContentTypeId + SEPARATOR + locale + SEPARATOR + mimeTypeId + SEPARATOR + + productConfigItem.get("configItemId") + SEPARATOR + encoderType + SEPARATOR + delegator; + String cachedValue = CONFIG_ITEM_CONTENT_CACHE.get(cacheKey); + if (cachedValue != null || CONFIG_ITEM_CONTENT_CACHE.containsKey(cacheKey)) { + return cachedValue; + } + + // Get content of given contentTypeId + boolean doCache = true; + String outString = null; + try { - String cachedValue = CONFIG_ITEM_CONTENT_CACHE.get(cacheKey); - if (cachedValue != null) { - return cachedValue; - } Writer outWriter = new StringWriter(); getProductConfigItemContentAsText(null, productConfigItem, confItemContentTypeId, locale, mimeTypeId, delegator, dispatcher, outWriter, false); - String outString = outWriter.toString(); - if (UtilValidate.isEmpty(outString)) { - outString = productConfigItem.getModelEntity().isField(candidateFieldName) ? productConfigItem.getString(candidateFieldName) : ""; - outString = outString == null ? "" : outString; - } - outString = encoder.sanitize(outString, null); - CONFIG_ITEM_CONTENT_CACHE.put(cacheKey, outString); - return outString; + outString = outWriter.toString(); } catch (GeneralException | IOException e) { - Debug.logError(e, "Error rendering ProdConfItemContent, inserting empty String", MODULE); - String candidateOut = productConfigItem.getModelEntity().isField(candidateFieldName) - ? productConfigItem.getString(candidateFieldName) : ""; - return candidateOut == null ? "" : encoder.sanitize(candidateOut, null); + Debug.logError(e, "Error rendering ProdConfItemContent", MODULE); + doCache = false; + } + + /* If we did not found any content (or got an error), get the content of a + * candidateFieldName matching the given contentTypeId + */ + if (UtilValidate.isEmpty(outString)) { + outString = ContentWrapper.getCandidateFieldValue(productConfigItem, confItemContentTypeId); } + // Encode found content via given encoderType + outString = ContentWrapper.encodeContentValue(outString, encoderType); + + if (doCache) { + CONFIG_ITEM_CONTENT_CACHE.put(cacheKey, outString); + } + return outString; } public static void getProductConfigItemContentAsText(String configItemId, GenericValue productConfigItem, String confItemContentTypeId, @@ -181,7 +191,7 @@ public class ProductConfigItemContentWrapper implements ContentWrapper { } if (UtilValidate.isEmpty(mimeTypeId)) { - mimeTypeId = EntityUtilProperties.getPropertyValue("content", "defaultMimeType", "text/html; charset=utf-8", delegator); + mimeTypeId = ContentWrapper.getDefaultMimeTypeId(delegator); } GenericValue productConfigItemContent = EntityQuery.use(delegator).from("ProdConfItemContent") @@ -198,23 +208,17 @@ public class ProductConfigItemContentWrapper implements ContentWrapper { inContext.put("productConfigItemContent", productConfigItemContent); ContentWorker.renderContentAsText(dispatcher, productConfigItemContent.getString("contentId"), outWriter, inContext, locale, mimeTypeId, null, null, cache); - return; - } - - String candidateFieldName = ModelUtil.dbNameToVarName(confItemContentTypeId); - ModelEntity productConfigItemModel = delegator.getModelEntity("ProductConfigItem"); - if (productConfigItemModel.isField(candidateFieldName)) { - if (productConfigItem == null) { - productConfigItem = EntityQuery.use(delegator).from("ProductConfigItem").where("configItemId", configItemId).cache().queryOne(); - } + } else { + String candidateValue = null; if (productConfigItem != null) { - String candidateValue = productConfigItem.getString(candidateFieldName); - if (UtilValidate.isNotEmpty(candidateValue)) { - outWriter.write(candidateValue); - return; - } + candidateValue = ContentWrapper.getCandidateFieldValue(productConfigItem, confItemContentTypeId); + } else { + candidateValue = ContentWrapper.getCandidateFieldValue(delegator, "ProductConfigItem", EntityCondition + .makeCondition("configItemId", configItemId), confItemContentTypeId, cache); + } + if (UtilValidate.isNotEmpty(candidateValue)) { + outWriter.write(candidateValue); } } } } - diff --git a/applications/product/src/main/java/org/apache/ofbiz/product/product/ProductContentWrapper.java b/applications/product/src/main/java/org/apache/ofbiz/product/product/ProductContentWrapper.java index 4e103cea8c..243a811f77 100644 --- a/applications/product/src/main/java/org/apache/ofbiz/product/product/ProductContentWrapper.java +++ b/applications/product/src/main/java/org/apache/ofbiz/product/product/ProductContentWrapper.java @@ -30,9 +30,7 @@ import javax.servlet.http.HttpServletRequest; import org.apache.ofbiz.base.util.Debug; import org.apache.ofbiz.base.util.GeneralException; -import org.apache.ofbiz.base.util.GeneralRuntimeException; import org.apache.ofbiz.base.util.StringUtil; -import org.apache.ofbiz.base.util.UtilCodec; import org.apache.ofbiz.base.util.UtilHttp; import org.apache.ofbiz.base.util.UtilValidate; import org.apache.ofbiz.base.util.cache.UtilCache; @@ -40,11 +38,8 @@ import org.apache.ofbiz.content.content.ContentWorker; import org.apache.ofbiz.content.content.ContentWrapper; import org.apache.ofbiz.entity.Delegator; import org.apache.ofbiz.entity.GenericValue; -import org.apache.ofbiz.entity.model.ModelEntity; -import org.apache.ofbiz.entity.model.ModelUtil; import org.apache.ofbiz.entity.util.EntityQuery; import org.apache.ofbiz.entity.util.EntityUtil; -import org.apache.ofbiz.entity.util.EntityUtilProperties; import org.apache.ofbiz.service.LocalDispatcher; /** @@ -77,8 +72,7 @@ public class ProductContentWrapper implements ContentWrapper { this.dispatcher = (LocalDispatcher) request.getAttribute("dispatcher"); this.product = product; this.locale = UtilHttp.getLocale(request); - this.mimeTypeId = EntityUtilProperties.getPropertyValue("content", "defaultMimeType", "text/html; charset=utf-8", - (Delegator) request.getAttribute("delegator")); + this.mimeTypeId = ContentWrapper.getDefaultMimeTypeId((Delegator) request.getAttribute("delegator")); } @Override @@ -94,7 +88,7 @@ public class ProductContentWrapper implements ContentWrapper { public static String getProductContentAsText(GenericValue product, String productContentTypeId, HttpServletRequest request, String encoderType) { LocalDispatcher dispatcher = (LocalDispatcher) request.getAttribute("dispatcher"); - String mimeTypeId = EntityUtilProperties.getPropertyValue("content", "defaultMimeType", "text/html; charset=utf-8", product.getDelegator()); + String mimeTypeId = ContentWrapper.getDefaultMimeTypeId(product.getDelegator()); return getProductContentAsText(product, productContentTypeId, UtilHttp.getLocale(request), mimeTypeId, null, null, product.getDelegator(), dispatcher, encoderType); } @@ -104,41 +98,56 @@ public class ProductContentWrapper implements ContentWrapper { return getProductContentAsText(product, productContentTypeId, locale, null, null, null, null, dispatcher, encoderType); } - public static String getProductContentAsText(GenericValue product, String productContentTypeId, Locale locale, String mimeTypeId, String partyId, + public static String getProductContentAsText(GenericValue product, String productContentTypeId, Locale locale, + String mimeTypeId, String partyId, String roleTypeId, Delegator delegator, LocalDispatcher dispatcher, String encoderType) { if (product == null) { return null; } - UtilCodec.SimpleEncoder encoder = UtilCodec.getEncoder(encoderType); - String candidateFieldName = ModelUtil.dbNameToVarName(productContentTypeId); - /* caching: there is one cache created, "product.content" Each product's content is cached with a key of - * contentTypeId::locale::mimeType::productId, or whatever the SEPARATOR is defined above to be. + /* + * Look for a previously cached entry (may also be an entry with null value if + * there was no content to retrieve) caching: there is one cache created, + * "product.content" Each product's content is cached with a key of + * contentTypeId::locale::mimeType::productId, or whatever the SEPARATOR is + * defined above to be. */ - String cacheKey = productContentTypeId + SEPARATOR + locale + SEPARATOR + mimeTypeId + SEPARATOR + product.get("productId") + SEPARATOR + String cacheKey = productContentTypeId + SEPARATOR + locale + SEPARATOR + mimeTypeId + SEPARATOR + product.get( + "productId") + SEPARATOR + encoderType + SEPARATOR + delegator; - try { - String cachedValue = PRODUCT_CONTENT_CACHE.get(cacheKey); - if (cachedValue != null) { - return cachedValue; - } + String cachedValue = PRODUCT_CONTENT_CACHE.get(cacheKey); + if (cachedValue != null || PRODUCT_CONTENT_CACHE.containsKey(cacheKey)) { + return cachedValue; + } + // Get content of given contentTypeId + boolean doCache = true; + String outString = null; + try { Writer outWriter = new StringWriter(); - getProductContentAsText(null, product, productContentTypeId, locale, mimeTypeId, partyId, roleTypeId, delegator, dispatcher, + getProductContentAsText(null, product, productContentTypeId, locale, mimeTypeId, partyId, roleTypeId, + delegator, dispatcher, outWriter, false); - String outString = outWriter.toString(); - if (UtilValidate.isEmpty(outString)) { - outString = product.getModelEntity().isField(candidateFieldName) ? product.getString(candidateFieldName) : ""; - outString = outString == null ? "" : outString; - } - outString = encoder.sanitize(outString, null); - PRODUCT_CONTENT_CACHE.put(cacheKey, outString); - return outString; + outString = outWriter.toString(); } catch (GeneralException | IOException e) { - Debug.logError(e, "Error rendering ProductContent, inserting empty String", MODULE); - String candidateOut = product.getModelEntity().isField(candidateFieldName) ? product.getString(candidateFieldName) : ""; - return candidateOut == null ? "" : encoder.sanitize(candidateOut, null); + Debug.logError(e, "Error rendering ProductContent", MODULE); + doCache = false; + } + + /* + * If we did not found any content (or got an error), get the content of a + * candidateFieldName matching the given contentTypeId + */ + if (UtilValidate.isEmpty(outString)) { + outString = ContentWrapper.getCandidateFieldValue(product, productContentTypeId); + } + // Encode found content via given encoderType + outString = ContentWrapper.encodeContentValue(outString, encoderType); + + if (doCache) { + PRODUCT_CONTENT_CACHE.put(cacheKey, outString); } + return outString; } public static void getProductContentAsText(String productId, GenericValue product, String productContentTypeId, Locale locale, String mimeTypeId, @@ -151,29 +160,30 @@ public class ProductContentWrapper implements ContentWrapper { public static void getProductContentAsText(String productId, GenericValue product, String productContentTypeId, Locale locale, String mimeTypeId, String partyId, String roleTypeId, Delegator delegator, LocalDispatcher dispatcher, Writer outWriter, boolean cache) throws GeneralException, IOException { - if (productId == null && product != null) { + if (product != null) { productId = product.getString("productId"); + } else if (productId != null) { + product = EntityQuery.use(delegator).from("Product").where("productId", productId).cache(cache).queryOne(); + } else { + throw new GeneralException("Missing parameter product or productId!"); } - if (delegator == null && product != null) { + if (delegator == null) { delegator = product.getDelegator(); } - if (UtilValidate.isEmpty(mimeTypeId)) { - mimeTypeId = EntityUtilProperties.getPropertyValue("content", "defaultMimeType", "text/html; charset=utf-8", delegator); - } - - if (delegator == null) { - throw new GeneralRuntimeException("Unable to find a delegator to use!"); + mimeTypeId = ContentWrapper.getDefaultMimeTypeId(delegator); } + GenericValue parentProduct = null; List<GenericValue> productContentList = EntityQuery.use(delegator).from("ProductContent").where("productId", productId, "productContentTypeId", productContentTypeId).orderBy("-fromDate").cache(cache).filterByDate().queryList(); - if (UtilValidate.isEmpty(productContentList) && ("Y".equals(product.getString("isVariant")))) { - GenericValue parent = ProductWorker.getParentProduct(productId, delegator); - if (parent != null) { - productContentList = EntityQuery.use(delegator).from("ProductContent").where("productId", parent.get("productId"), - "productContentTypeId", productContentTypeId).orderBy("-fromDate").cache(cache).filterByDate().queryList(); + if (UtilValidate.isEmpty(productContentList) && ("Y".equals(product.get("isVariant")))) { + parentProduct = ProductWorker.getParentProduct(productId, delegator); + if (parentProduct != null) { + productContentList = EntityQuery.use(delegator).from("ProductContent").where("productId", parentProduct + .get("productId"), "productContentTypeId", productContentTypeId).orderBy("-fromDate").cache( + cache).filterByDate().queryList(); } } GenericValue productContent = EntityUtil.getFirst(productContentList); @@ -184,34 +194,13 @@ public class ProductContentWrapper implements ContentWrapper { inContext.put("productContent", productContent); ContentWorker.renderContentAsText(dispatcher, productContent.getString("contentId"), outWriter, inContext, locale, mimeTypeId, partyId, roleTypeId, cache); - return; - } - - String candidateFieldName = ModelUtil.dbNameToVarName(productContentTypeId); - ModelEntity productModel = delegator.getModelEntity("Product"); - if (product == null) { - product = EntityQuery.use(delegator).from("Product").where("productId", productId).cache().queryOne(); - } - if (UtilValidate.isEmpty(product)) { - Debug.logWarning("No Product entity found for productId: " + productId, MODULE); - return; - } - - if (productModel.isField(candidateFieldName)) { - String candidateValue = product.getString(candidateFieldName); + } else { + String candidateValue = ContentWrapper.getCandidateFieldValue(product, productContentTypeId); + if (UtilValidate.isEmpty(candidateValue) && parentProduct != null) { + candidateValue = ContentWrapper.getCandidateFieldValue(parentProduct, productContentTypeId); + } if (UtilValidate.isNotEmpty(candidateValue)) { outWriter.write(candidateValue); - return; - } else if ("Y".equals(product.getString("isVariant"))) { - // look up the virtual product - GenericValue parent = ProductWorker.getParentProduct(productId, delegator); - if (parent != null) { - candidateValue = parent.getString(candidateFieldName); - if (UtilValidate.isNotEmpty(candidateValue)) { - outWriter.write(candidateValue); - return; - } - } } } } diff --git a/applications/product/src/main/java/org/apache/ofbiz/product/product/ProductPromoContentWrapper.java b/applications/product/src/main/java/org/apache/ofbiz/product/product/ProductPromoContentWrapper.java index 83f818a2e2..70fcfe69e1 100644 --- a/applications/product/src/main/java/org/apache/ofbiz/product/product/ProductPromoContentWrapper.java +++ b/applications/product/src/main/java/org/apache/ofbiz/product/product/ProductPromoContentWrapper.java @@ -33,7 +33,6 @@ import org.apache.ofbiz.base.util.Debug; import org.apache.ofbiz.base.util.GeneralException; import org.apache.ofbiz.base.util.GeneralRuntimeException; import org.apache.ofbiz.base.util.StringUtil; -import org.apache.ofbiz.base.util.UtilCodec; import org.apache.ofbiz.base.util.UtilHttp; import org.apache.ofbiz.base.util.UtilValidate; import org.apache.ofbiz.base.util.cache.UtilCache; @@ -44,11 +43,8 @@ import org.apache.ofbiz.entity.GenericValue; import org.apache.ofbiz.entity.condition.EntityCondition; import org.apache.ofbiz.entity.condition.EntityExpr; import org.apache.ofbiz.entity.condition.EntityOperator; -import org.apache.ofbiz.entity.model.ModelEntity; -import org.apache.ofbiz.entity.model.ModelUtil; import org.apache.ofbiz.entity.util.EntityQuery; import org.apache.ofbiz.entity.util.EntityUtil; -import org.apache.ofbiz.entity.util.EntityUtilProperties; import org.apache.ofbiz.service.LocalDispatcher; /** @@ -82,8 +78,7 @@ public class ProductPromoContentWrapper implements ContentWrapper { this.dispatcher = (LocalDispatcher) request.getAttribute("dispatcher"); this.productPromo = productPromo; this.locale = UtilHttp.getLocale(request); - this.mimeTypeId = EntityUtilProperties.getPropertyValue("content", "defaultMimeType", "text/html; charset=utf-8", - (Delegator) request.getAttribute("delegator")); + this.mimeTypeId = ContentWrapper.getDefaultMimeTypeId((Delegator) request.getAttribute("delegator")); } @Override @@ -102,7 +97,7 @@ public class ProductPromoContentWrapper implements ContentWrapper { LocalDispatcher dispatcher = (LocalDispatcher) request.getAttribute("dispatcher"); Delegator delegator = (Delegator) request.getAttribute("delegator"); return getProductPromoContentAsText(productPromo, productPromoContentTypeId, UtilHttp.getLocale(request), - EntityUtilProperties.getPropertyValue("content", "defaultMimeType", "text/html; charset=utf-8", delegator), + ContentWrapper.getDefaultMimeTypeId(delegator), null, null, productPromo.getDelegator(), dispatcher, encoderType); } @@ -117,35 +112,45 @@ public class ProductPromoContentWrapper implements ContentWrapper { return null; } - UtilCodec.SimpleEncoder encoder = UtilCodec.getEncoder(encoderType); - String candidateFieldName = ModelUtil.dbNameToVarName(productPromoContentTypeId); + /* Look for a previously cached entry (may also be an entry with null value if + * there was no content to retrieve) + */ /* caching: there is one cache created, "product.promo.content" Each productPromo's content is cached with a key of * contentTypeId::locale::mimeType::productPromoId, or whatever the SEPARATOR is defined above to be. */ String cacheKey = productPromoContentTypeId + SEPARATOR + locale + SEPARATOR + mimeTypeId + SEPARATOR + productPromo.get("productPromoId") + SEPARATOR + encoderType + SEPARATOR + delegator; - try { - String cachedValue = PRODUCT_PROMO_CONTENT_CACHE.get(cacheKey); - if (cachedValue != null) { - return cachedValue; - } + String cachedValue = PRODUCT_PROMO_CONTENT_CACHE.get(cacheKey); + if (cachedValue != null || PRODUCT_PROMO_CONTENT_CACHE.containsKey(cacheKey)) { + return cachedValue; + } + // Get content of given contentTypeId + boolean doCache = true; + String outString = null; + try { Writer outWriter = new StringWriter(); getProductPromoContentAsText(null, productPromo, productPromoContentTypeId, locale, mimeTypeId, partyId, roleTypeId, delegator, dispatcher, outWriter, false); - String outString = outWriter.toString(); - if (UtilValidate.isEmpty(outString)) { - outString = productPromo.getModelEntity().isField(candidateFieldName) ? productPromo.getString(candidateFieldName) : ""; - outString = outString == null ? "" : outString; - } - outString = encoder.sanitize(outString, null); - PRODUCT_PROMO_CONTENT_CACHE.put(cacheKey, outString); - return outString; + outString = outWriter.toString(); } catch (GeneralException | IOException e) { - Debug.logError(e, "Error rendering ProductPromoContent, inserting empty String", MODULE); - String candidateOut = productPromo.getModelEntity().isField(candidateFieldName) ? productPromo.getString(candidateFieldName) : ""; - return candidateOut == null ? "" : encoder.sanitize(candidateOut, null); + Debug.logError(e, "Error rendering ProductPromoContent", MODULE); + doCache = false; } + + /* If we did not found any content (or got an error), get the content of a + * candidateFieldName matching the given contentTypeId + */ + if (UtilValidate.isEmpty(outString)) { + outString = ContentWrapper.getCandidateFieldValue(productPromo, productPromoContentTypeId); + } + // Encode found content via given encoderType + outString = ContentWrapper.encodeContentValue(outString, encoderType); + + if (doCache) { + PRODUCT_PROMO_CONTENT_CACHE.put(cacheKey, outString); + } + return outString; } public static void getProductPromoContentAsText(String productPromoId, GenericValue productPromo, String productPromoContentTypeId, @@ -167,7 +172,7 @@ public class ProductPromoContentWrapper implements ContentWrapper { } if (UtilValidate.isEmpty(mimeTypeId)) { - mimeTypeId = EntityUtilProperties.getPropertyValue("content", "defaultMimeType", "text/html; charset=utf-8", delegator); + mimeTypeId = ContentWrapper.getDefaultMimeTypeId(delegator); } if (UtilValidate.isEmpty(delegator)) { @@ -192,21 +197,16 @@ public class ProductPromoContentWrapper implements ContentWrapper { inContext.put("productPromoContent", productPromoContent); ContentWorker.renderContentAsText(dispatcher, productPromoContent.getString("contentId"), outWriter, inContext, locale, mimeTypeId, partyId, roleTypeId, cache); - return; - } - - String candidateFieldName = ModelUtil.dbNameToVarName(productPromoContentTypeId); - ModelEntity productModel = delegator.getModelEntity("ProductPromo"); - if (productModel.isField(candidateFieldName)) { - if (UtilValidate.isEmpty(productPromo)) { - productPromo = EntityQuery.use(delegator).from("ProductPromo").where("productPromoId", productPromoId).cache().queryOne(); - } + } else { + String candidateValue = null; if (productPromo != null) { - String candidateValue = productPromo.getString(candidateFieldName); - if (UtilValidate.isNotEmpty(candidateValue)) { - outWriter.write(candidateValue); - return; - } + candidateValue = ContentWrapper.getCandidateFieldValue(productPromo, productPromoContentTypeId); + } else { + candidateValue = ContentWrapper.getCandidateFieldValue(delegator, "ProductPromo", EntityCondition + .makeCondition("productPromoId", productPromoId), productPromoContentTypeId, cache); + } + if (UtilValidate.isNotEmpty(candidateValue)) { + outWriter.write(candidateValue); } } }