blob: ed9c3b0b345727be94641f3993cb96777c4d63d6 [file] [log] [blame]
/*******************************************************************************
* 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.ofbiz.product.category.ftl;
import java.io.IOException;
import java.io.Writer;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javolution.util.FastList;
import javolution.util.FastMap;
import org.apache.oro.text.regex.MalformedPatternException;
import org.apache.oro.text.regex.Pattern;
import org.apache.oro.text.regex.Perl5Compiler;
import org.apache.oro.text.regex.Perl5Matcher;
import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.StringUtil;
import org.ofbiz.base.util.StringUtil.StringWrapper;
import org.ofbiz.base.util.UtilMisc;
import org.ofbiz.base.util.UtilValidate;
import org.ofbiz.common.UrlServletHelper;
import org.ofbiz.entity.Delegator;
import org.ofbiz.entity.GenericEntityException;
import org.ofbiz.entity.GenericValue;
import org.ofbiz.entity.condition.EntityCondition;
import org.ofbiz.entity.condition.EntityExpr;
import org.ofbiz.entity.condition.EntityOperator;
import org.ofbiz.product.category.CatalogUrlServlet;
import org.ofbiz.product.category.CategoryContentWrapper;
import org.ofbiz.product.category.CategoryWorker;
import org.ofbiz.product.category.SeoConfigUtil;
import org.ofbiz.product.category.SeoUrlUtil;
import org.ofbiz.product.product.ProductContentWrapper;
import freemarker.core.Environment;
import freemarker.ext.beans.BeanModel;
import freemarker.ext.beans.StringModel;
import freemarker.template.SimpleScalar;
import freemarker.template.TemplateModelException;
import freemarker.template.TemplateTransformModel;
public class CatalogUrlSeoTransform implements TemplateTransformModel {
public final static String module = CatalogUrlSeoTransform.class.getName();
private static Map<String, String> categoryNameIdMap = null;
private static Map<String, String> categoryIdNameMap = null;
private static boolean categoryMapInitialed = false;
private static final String asciiRegexp = "^[0-9-_a-zA-Z]*$";
private static Pattern asciiPattern = null;
public static final String URL_HYPHEN = "-";
static {
if (!SeoConfigUtil.isInitialed()) {
SeoConfigUtil.init();
}
try {
Perl5Compiler perlCompiler = new Perl5Compiler();
asciiPattern = perlCompiler.compile(asciiRegexp, Perl5Compiler.READ_ONLY_MASK);
} catch (MalformedPatternException e1) {
Debug.logWarning(e1, module);
}
}
public String getStringArg(Map args, String key) {
Object o = args.get(key);
if (o instanceof SimpleScalar) {
return ((SimpleScalar) o).getAsString();
} else if (o instanceof StringModel) {
return ((StringModel) o).getAsString();
}
return null;
}
@Override
public Writer getWriter(final Writer out, final Map args)
throws TemplateModelException, IOException {
final StringBuilder buf = new StringBuilder();
return new Writer(out) {
@Override
public void write(char[] cbuf, int off, int len) throws IOException {
buf.append(cbuf, off, len);
}
@Override
public void flush() throws IOException {
out.flush();
}
@Override
public void close() throws IOException {
try {
Environment env = Environment.getCurrentEnvironment();
BeanModel req = (BeanModel) env.getVariable("request");
if (req != null) {
String productId = getStringArg(args, "productId");
String currentCategoryId = getStringArg(args, "currentCategoryId");
String previousCategoryId = getStringArg(args, "previousCategoryId");
HttpServletRequest request = (HttpServletRequest) req.getWrappedObject();
if (!isCategoryMapInitialed()) {
initCategoryMap(request);
}
String catalogUrl = "";
if (SeoConfigUtil.isCategoryUrlEnabled(request.getContextPath())) {
if (UtilValidate.isEmpty(productId)) {
catalogUrl = makeCategoryUrl(request, currentCategoryId, previousCategoryId, null, null, null, null);
} else {
catalogUrl = makeProductUrl(request, productId, currentCategoryId, previousCategoryId);
}
} else {
catalogUrl = CatalogUrlServlet.makeCatalogUrl(request, productId, currentCategoryId, previousCategoryId);
}
out.write(catalogUrl);
}
} catch (TemplateModelException e) {
throw new IOException(e.getMessage());
}
}
};
}
/**
* Check whether the category map is initialed.
*
* @return a boolean value to indicate whether the category map has been initialized.
*/
public static boolean isCategoryMapInitialed() {
return categoryMapInitialed;
}
/**
* Get the category name/id map.
*
* @return the category name/id map
*/
public static Map<String, String> getCategoryNameIdMap() {
return categoryNameIdMap;
}
/**
* Get the category id/name map.
*
* @return the category id/name map
*/
public static Map<String, String> getCategoryIdNameMap() {
return categoryIdNameMap;
}
/**
* Initial category-name/category-id map.
* Note: as a key, the category-name should be:
* 1. ascii
* 2. lower cased and use hyphen between the words.
* If not, the category id will be used.
*
*/
public static synchronized void initCategoryMap(HttpServletRequest request) {
Delegator delegator = (Delegator) request.getAttribute("delegator");
initCategoryMap(request, delegator);
}
public static synchronized void initCategoryMap(HttpServletRequest request, Delegator delegator) {
if (SeoConfigUtil.checkCategoryUrl()) {
categoryNameIdMap = FastMap.newInstance();
categoryIdNameMap = FastMap.newInstance();
Perl5Matcher matcher = new Perl5Matcher();
try {
Collection<GenericValue> allCategories = delegator.findList("ProductCategory", null, UtilMisc.toSet("productCategoryId", "categoryName"), null, null, false);
for (GenericValue category : allCategories) {
String categoryName = category.getString("categoryName");
String categoryNameId = null;
String categoryIdName = null;
String categoryId = category.getString("productCategoryId");
if (UtilValidate.isNotEmpty(categoryName)) {
categoryName = SeoUrlUtil.replaceSpecialCharsUrl(categoryName.trim());
if (matcher.matches(categoryName, asciiPattern)) {
categoryIdName = categoryName.replaceAll(" ", URL_HYPHEN);
categoryNameId = categoryIdName + URL_HYPHEN + categoryId.trim().replaceAll(" ", URL_HYPHEN);
} else {
categoryIdName = categoryId.trim().replaceAll(" ", URL_HYPHEN);
categoryNameId = categoryIdName;
}
} else {
GenericValue productCategory = delegator.findOne("ProductCategory", UtilMisc.toMap("productCategoryId", categoryId), true);
CategoryContentWrapper wrapper = new CategoryContentWrapper(productCategory, request);
StringWrapper alternativeUrl = wrapper.get("ALTERNATIVE_URL");
if (UtilValidate.isNotEmpty(alternativeUrl) && UtilValidate.isNotEmpty(alternativeUrl.toString())) {
categoryIdName = SeoUrlUtil.replaceSpecialCharsUrl(alternativeUrl.toString());
categoryNameId = categoryIdName + URL_HYPHEN + categoryId.trim().replaceAll(" ", URL_HYPHEN);
} else {
categoryNameId = categoryId.trim().replaceAll(" ", URL_HYPHEN);
categoryIdName = categoryNameId;
}
}
if (categoryNameIdMap.containsKey(categoryNameId)) {
categoryNameId = categoryId.trim().replaceAll(" ", URL_HYPHEN);
categoryIdName = categoryNameId;
}
if (!matcher.matches(categoryNameId, asciiPattern) || categoryNameIdMap.containsKey(categoryNameId)) {
continue;
}
categoryNameIdMap.put(categoryNameId, categoryId);
categoryIdNameMap.put(categoryId, categoryIdName);
}
} catch (GenericEntityException e) {
Debug.logError(e, module);
}
}
categoryMapInitialed = true;
}
/**
* Make product url according to the configurations.
*
* @return String a catalog url
*/
public static String makeProductUrl(HttpServletRequest request, String productId, String currentCategoryId, String previousCategoryId) {
Delegator delegator = (Delegator) request.getAttribute("delegator");
if (!isCategoryMapInitialed()) {
initCategoryMap(request);
}
String contextPath = request.getContextPath();
StringBuilder urlBuilder = new StringBuilder();
GenericValue product = null;
urlBuilder.append((request.getSession().getServletContext()).getContextPath());
if (urlBuilder.charAt(urlBuilder.length() - 1) != '/') {
urlBuilder.append("/");
}
if (UtilValidate.isNotEmpty(productId)) {
try {
product = delegator.findOne("Product", UtilMisc.toMap("productId", productId), true);
} catch (GenericEntityException e) {
Debug.logError(e, "Error looking up product info for productId [" + productId + "]: " + e.toString(), module);
}
}
if (product != null) {
urlBuilder.append(CatalogUrlServlet.PRODUCT_REQUEST + "/");
}
if (UtilValidate.isNotEmpty(currentCategoryId)) {
List<String> trail = CategoryWorker.getTrail(request);
trail = CategoryWorker.adjustTrail(trail, currentCategoryId, previousCategoryId);
if (!SeoConfigUtil.isCategoryUrlEnabled(contextPath)) {
for (String trailCategoryId: trail) {
if ("TOP".equals(trailCategoryId)) continue;
urlBuilder.append("/");
urlBuilder.append(trailCategoryId);
}
} else {
if (trail.size() > 1) {
String lastCategoryId = trail.get(trail.size() - 1);
if (!"TOP".equals(lastCategoryId)) {
if (SeoConfigUtil.isCategoryNameEnabled()) {
String categoryName = CatalogUrlSeoTransform.getCategoryIdNameMap().get(lastCategoryId);
if (UtilValidate.isNotEmpty(categoryName)) {
urlBuilder.append(categoryName);
if (product != null) {
urlBuilder.append(URL_HYPHEN);
}
}
}
}
}
}
}
if (UtilValidate.isNotEmpty(productId)) {
if (product != null) {
String productName = product.getString("productName");
productName = SeoUrlUtil.replaceSpecialCharsUrl(productName);
if (UtilValidate.isNotEmpty(productName)) {
urlBuilder.append(productName + URL_HYPHEN);
} else {
ProductContentWrapper wrapper = new ProductContentWrapper(product, request);
StringWrapper alternativeUrl = wrapper.get("ALTERNATIVE_URL");
if (UtilValidate.isNotEmpty(alternativeUrl) && UtilValidate.isNotEmpty(alternativeUrl.toString())) {
productName = SeoUrlUtil.replaceSpecialCharsUrl(alternativeUrl.toString());
if (UtilValidate.isNotEmpty(productName)) {
urlBuilder.append(productName + URL_HYPHEN);
}
}
}
}
try {
//SeoConfigUtil.addSpecialProductId(productId);
urlBuilder.append(productId);
} catch (Exception e) {
urlBuilder.append(productId);
}
}
if (!urlBuilder.toString().endsWith("/") && UtilValidate.isNotEmpty(SeoConfigUtil.getCategoryUrlSuffix())) {
urlBuilder.append(SeoConfigUtil.getCategoryUrlSuffix());
}
return urlBuilder.toString();
}
/**
* Make category url according to the configurations.
*
* @return String a category url
*/
public static String makeCategoryUrl(HttpServletRequest request, String currentCategoryId, String previousCategoryId, String viewSize, String viewIndex, String viewSort, String searchString) {
if (!isCategoryMapInitialed()) {
initCategoryMap(request);
}
StringBuilder urlBuilder = new StringBuilder();
urlBuilder.append((request.getSession().getServletContext()).getContextPath());
if (urlBuilder.charAt(urlBuilder.length() - 1) != '/') {
urlBuilder.append("/");
}
urlBuilder.append(CatalogUrlServlet.CATEGORY_REQUEST + "/");
if (UtilValidate.isNotEmpty(currentCategoryId)) {
List<String> trail = CategoryWorker.getTrail(request);
trail = CategoryWorker.adjustTrail(trail, currentCategoryId, previousCategoryId);
if (trail.size() > 1) {
String lastCategoryId = trail.get(trail.size() - 1);
if (!"TOP".equals(lastCategoryId)) {
String categoryName = CatalogUrlSeoTransform.getCategoryIdNameMap().get(lastCategoryId);
if (UtilValidate.isNotEmpty(categoryName)) {
urlBuilder.append(categoryName);
urlBuilder.append(URL_HYPHEN);
urlBuilder.append(lastCategoryId.trim().replaceAll(" ", URL_HYPHEN));
} else {
urlBuilder.append(lastCategoryId.trim().replaceAll(" ", URL_HYPHEN));
}
}
}
}
if (!urlBuilder.toString().endsWith("/") && UtilValidate.isNotEmpty(SeoConfigUtil.getCategoryUrlSuffix())) {
urlBuilder.append(SeoConfigUtil.getCategoryUrlSuffix());
}
// append view index
if (UtilValidate.isNotEmpty(viewIndex)) {
if (!urlBuilder.toString().endsWith("?") && !urlBuilder.toString().endsWith("&")) {
urlBuilder.append("?");
}
urlBuilder.append("viewIndex=" + viewIndex + "&");
}
// append view size
if (UtilValidate.isNotEmpty(viewSize)) {
if (!urlBuilder.toString().endsWith("?") && !urlBuilder.toString().endsWith("&")) {
urlBuilder.append("?");
}
urlBuilder.append("viewSize=" + viewSize + "&");
}
// append view sort
if (UtilValidate.isNotEmpty(viewSort)) {
if (!urlBuilder.toString().endsWith("?") && !urlBuilder.toString().endsWith("&")) {
urlBuilder.append("?");
}
urlBuilder.append("viewSort=" + viewSort + "&");
}
// append search string
if (UtilValidate.isNotEmpty(searchString)) {
if (!urlBuilder.toString().endsWith("?") && !urlBuilder.toString().endsWith("&")) {
urlBuilder.append("?");
}
urlBuilder.append("searchString=" + searchString + "&");
}
if (urlBuilder.toString().endsWith("&")) {
return urlBuilder.toString().substring(0, urlBuilder.toString().length()-1);
}
return urlBuilder.toString();
}
/**
* Make product url according to the configurations.
*
* @return String a catalog url
*/
public static String makeProductUrl(String contextPath, List<String> trail, String productId, String productName, String currentCategoryId, String previousCategoryId) {
StringBuilder urlBuilder = new StringBuilder();
urlBuilder.append(contextPath);
if (urlBuilder.charAt(urlBuilder.length() - 1) != '/') {
urlBuilder.append("/");
}
if (!SeoConfigUtil.isCategoryUrlEnabled(contextPath)) {
urlBuilder.append(CatalogUrlServlet.CATALOG_URL_MOUNT_POINT);
} else {
urlBuilder.append(CatalogUrlServlet.PRODUCT_REQUEST + "/");
}
if (UtilValidate.isNotEmpty(currentCategoryId)) {
trail = CategoryWorker.adjustTrail(trail, currentCategoryId, previousCategoryId);
if (!SeoConfigUtil.isCategoryUrlEnabled(contextPath)) {
for (String trailCategoryId: trail) {
if ("TOP".equals(trailCategoryId)) continue;
urlBuilder.append("/");
urlBuilder.append(trailCategoryId);
}
} else {
if (trail.size() > 1) {
String lastCategoryId = trail.get(trail.size() - 1);
if (!"TOP".equals(lastCategoryId)) {
if (SeoConfigUtil.isCategoryNameEnabled()) {
String categoryName = CatalogUrlSeoTransform.getCategoryIdNameMap().get(lastCategoryId);
if (UtilValidate.isNotEmpty(categoryName)) {
urlBuilder.append(categoryName + URL_HYPHEN);
}
}
}
}
}
}
if (UtilValidate.isNotEmpty(productId)) {
if (!SeoConfigUtil.isCategoryUrlEnabled(contextPath)) {
urlBuilder.append("/p_");
} else {
productName = SeoUrlUtil.replaceSpecialCharsUrl(productName);
if (UtilValidate.isNotEmpty(productName)) {
urlBuilder.append(productName + URL_HYPHEN);
}
}
urlBuilder.append(productId);
}
if (!urlBuilder.toString().endsWith("/") && UtilValidate.isNotEmpty(SeoConfigUtil.getCategoryUrlSuffix())) {
urlBuilder.append(SeoConfigUtil.getCategoryUrlSuffix());
}
return urlBuilder.toString();
}
/**
* Get a string lower cased and hyphen connected.
*
* @param name a String to be transformed
* @return String nice name
*/
protected static String getNiceName(String name) {
Perl5Matcher matcher = new Perl5Matcher();
String niceName = null;
if (UtilValidate.isNotEmpty(name)) {
name = name.trim().replaceAll(" ", URL_HYPHEN);
if (UtilValidate.isNotEmpty(name) && matcher.matches(name, asciiPattern)) {
niceName = name;
}
}
return niceName;
}
public static boolean forwardProductUri(HttpServletRequest request, HttpServletResponse response, Delegator delegator) throws ServletException, IOException {
return forwardProductUri(request, response, delegator, null);
}
public static boolean forwardProductUri(HttpServletRequest request, HttpServletResponse response, Delegator delegator, String controlServlet) throws ServletException, IOException {
return forwardUri(request, response, delegator, controlServlet);
}
/**
* Forward a uri according to forward pattern regular expressions.
*
* @param uri
* String to reverse transform
* @return boolean to indicate whether the uri is forwarded.
* @throws IOException
* @throws ServletException
*/
public static boolean forwardUri(HttpServletRequest request, HttpServletResponse response, Delegator delegator, String controlServlet) throws ServletException, IOException {
String pathInfo = request.getRequestURI();
String contextPath = request.getContextPath();
if (!isCategoryMapInitialed()) {
initCategoryMap(request, delegator);
}
if (!SeoConfigUtil.isCategoryUrlEnabled(contextPath)) {
return false;
}
List<String> pathElements = StringUtil.split(pathInfo, "/");
if (UtilValidate.isEmpty(pathElements)) {
return false;
}
// remove context path
pathInfo = SeoUrlUtil.removeContextPath(pathInfo, contextPath);
// remove servlet path
pathInfo = SeoUrlUtil.removeContextPath(pathInfo, request.getServletPath());
if (pathInfo.startsWith("/" + CatalogUrlServlet.CATEGORY_REQUEST + "/")) {
return forwardCategoryUri(request, response, delegator, controlServlet);
}
String lastPathElement = pathElements.get(pathElements.size() - 1);
String categoryId = null;
String productId = null;
if (UtilValidate.isNotEmpty(lastPathElement)) {
if (UtilValidate.isNotEmpty(SeoConfigUtil.getCategoryUrlSuffix())) {
if (lastPathElement.endsWith(SeoConfigUtil.getCategoryUrlSuffix())) {
lastPathElement = lastPathElement.substring(0, lastPathElement.length() - SeoConfigUtil.getCategoryUrlSuffix().length());
} else {
return false;
}
}
if (SeoConfigUtil.isCategoryNameEnabled() || pathInfo.startsWith("/" + CatalogUrlServlet.CATEGORY_REQUEST + "/")) {
for (String categoryName : categoryNameIdMap.keySet()) {
if (lastPathElement.startsWith(categoryName)) {
categoryId = categoryNameIdMap.get(categoryName);
if (!lastPathElement.equals(categoryName)) {
lastPathElement = lastPathElement.substring(categoryName.length() + URL_HYPHEN.length());
}
break;
}
}
if (UtilValidate.isEmpty(categoryId)) {
categoryId = lastPathElement;
}
}
if (UtilValidate.isNotEmpty(lastPathElement)) {
List<String> urlElements = StringUtil.split(lastPathElement, URL_HYPHEN);
if (UtilValidate.isEmpty(urlElements)) {
try {
if (delegator.findOne("Product", UtilMisc.toMap("productId", lastPathElement), true) != null) {
productId = lastPathElement;
}
} catch (GenericEntityException e) {
Debug.logError(e, "Error looking up product info for ProductUrl with path info [" + pathInfo + "]: " + e.toString(), module);
}
} else {
int i = urlElements.size() - 1;
String tempProductId = urlElements.get(i);
while (i >= 0) {
try {
List<EntityExpr> exprs = FastList.newInstance();
exprs.add(EntityCondition.makeCondition("productId", EntityOperator.EQUALS, lastPathElement));
// if (SeoConfigUtil.isSpecialProductId(tempProductId)) {
// exprs.add(EntityCondition.makeCondition("productId", EntityOperator.EQUALS, SeoConfigUtil.getSpecialProductId(tempProductId)));
// } else {
exprs.add(EntityCondition.makeCondition("productId", EntityOperator.EQUALS, tempProductId));
// }
List<GenericValue> products = delegator.findList("Product", EntityCondition.makeCondition(exprs, EntityOperator.OR), UtilMisc.toSet("productId", "productName"), null, null, true);
if (products != null && products.size() > 0) {
if (products.size() == 1) {
productId = products.get(0).getString("productId");
break;
} else {
productId = tempProductId;
break;
}
} else if (i > 0) {
tempProductId = urlElements.get(i - 1) + URL_HYPHEN + tempProductId;
}
} catch (GenericEntityException e) {
Debug.logError(e, "Error looking up product info for ProductUrl with path info [" + pathInfo + "]: " + e.toString(), module);
}
i--;
}
}
}
}
if (UtilValidate.isNotEmpty(productId) || UtilValidate.isNotEmpty(categoryId)) {
if (categoryId != null) {
request.setAttribute("productCategoryId", categoryId);
}
if (productId != null) {
request.setAttribute("product_id", productId);
request.setAttribute("productId", productId);
}
StringBuilder urlBuilder = new StringBuilder();
if (UtilValidate.isNotEmpty(controlServlet)) {
urlBuilder.append("/" + controlServlet);
}
urlBuilder.append("/" + (productId != null ? CatalogUrlServlet.PRODUCT_REQUEST : CatalogUrlServlet.CATEGORY_REQUEST));
UrlServletHelper.setViewQueryParameters(request, urlBuilder);
Debug.logInfo("[Filtered request]: " + pathInfo + " (" + urlBuilder + ")", module);
RequestDispatcher rd = request.getRequestDispatcher(urlBuilder.toString());
rd.forward(request, response);
return true;
}
return false;
}
/**
* Forward a category uri according to forward pattern regular expressions.
*
* @param uri
* String to reverse transform
* @return String
* @throws IOException
* @throws ServletException
*/
public static boolean forwardCategoryUri(HttpServletRequest request, HttpServletResponse response, Delegator delegator, String controlServlet) throws ServletException, IOException {
String pathInfo = request.getRequestURI();
String contextPath = request.getContextPath();
if (!isCategoryMapInitialed()) {
initCategoryMap(request);
}
if (!SeoConfigUtil.isCategoryUrlEnabled(contextPath)) {
return false;
}
List<String> pathElements = StringUtil.split(pathInfo, "/");
if (UtilValidate.isEmpty(pathElements)) {
return false;
}
String lastPathElement = pathElements.get(pathElements.size() - 1);
String categoryId = null;
if (UtilValidate.isNotEmpty(lastPathElement)) {
if (UtilValidate.isNotEmpty(SeoConfigUtil.getCategoryUrlSuffix())) {
if (lastPathElement.endsWith(SeoConfigUtil.getCategoryUrlSuffix())) {
lastPathElement = lastPathElement.substring(0, lastPathElement.length() - SeoConfigUtil.getCategoryUrlSuffix().length());
} else {
return false;
}
}
for (String categoryName : categoryNameIdMap.keySet()) {
if (lastPathElement.startsWith(categoryName)) {
categoryId = categoryNameIdMap.get(categoryName);
break;
}
}
if (UtilValidate.isEmpty(categoryId)) {
categoryId = lastPathElement.trim();
}
}
if (UtilValidate.isNotEmpty(categoryId)) {
request.setAttribute("productCategoryId", categoryId);
StringBuilder urlBuilder = new StringBuilder();
if (UtilValidate.isNotEmpty(controlServlet)) {
urlBuilder.append("/" + controlServlet);
}
urlBuilder.append("/" + CatalogUrlServlet.CATEGORY_REQUEST);
UrlServletHelper.setViewQueryParameters(request, urlBuilder);
Debug.logInfo("[Filtered request]: " + pathInfo + " (" + urlBuilder + ")", module);
RequestDispatcher rd = request.getRequestDispatcher(urlBuilder.toString());
rd.forward(request, response);
return true;
}
return false;
}
/**
* This is used when building product url in services.
*
* @param delegator
* @param wrapper
* @param prefix
* @param contextPath
* @param productCategoryId
* @param previousCategoryId
* @param productId
* @return
*/
public static String makeProductUrl(Delegator delegator, ProductContentWrapper wrapper, String prefix, String contextPath, String currentCategoryId, String previousCategoryId,
String productId) {
StringBuilder urlBuilder = new StringBuilder();
GenericValue product = null;
urlBuilder.append(prefix);
if (urlBuilder.charAt(urlBuilder.length() - 1) != '/') {
urlBuilder.append("/");
}
if (UtilValidate.isNotEmpty(productId)) {
try {
product = delegator.findOne("Product", UtilMisc.toMap("productId", productId), true);
} catch (GenericEntityException e) {
Debug.logError(e, "Error looking up product info for productId [" + productId + "]: " + e.toString(), module);
}
}
if (product != null) {
urlBuilder.append(CatalogUrlServlet.PRODUCT_REQUEST + "/");
}
if (UtilValidate.isNotEmpty(currentCategoryId)) {
List<String> trail = null;
trail = CategoryWorker.adjustTrail(trail, currentCategoryId, previousCategoryId);
if (!SeoConfigUtil.isCategoryUrlEnabled(contextPath)) {
for (String trailCategoryId: trail) {
if ("TOP".equals(trailCategoryId)) continue;
urlBuilder.append("/");
urlBuilder.append(trailCategoryId);
}
} else {
if (trail != null && trail.size() > 1) {
String lastCategoryId = trail.get(trail.size() - 1);
if (!"TOP".equals(lastCategoryId)) {
if (SeoConfigUtil.isCategoryNameEnabled()) {
String categoryName = CatalogUrlSeoTransform.getCategoryIdNameMap().get(lastCategoryId);
if (UtilValidate.isNotEmpty(categoryName)) {
urlBuilder.append(categoryName);
if (product != null) {
urlBuilder.append(URL_HYPHEN);
}
}
}
}
}
}
}
if (UtilValidate.isNotEmpty(productId)) {
if (product != null) {
String productName = product.getString("productName");
productName = SeoUrlUtil.replaceSpecialCharsUrl(productName);
if (UtilValidate.isNotEmpty(productName)) {
urlBuilder.append(productName + URL_HYPHEN);
} else {
StringWrapper alternativeUrl = wrapper.get("ALTERNATIVE_URL");
if (UtilValidate.isNotEmpty(alternativeUrl) && UtilValidate.isNotEmpty(alternativeUrl.toString())) {
productName = SeoUrlUtil.replaceSpecialCharsUrl(alternativeUrl.toString());
if (UtilValidate.isNotEmpty(productName)) {
urlBuilder.append(productName + URL_HYPHEN);
}
}
}
}
try {
//SeoConfigUtil.addSpecialProductId(productId);
urlBuilder.append(productId);
} catch (Exception e) {
urlBuilder.append(productId);
}
}
if (!urlBuilder.toString().endsWith("/") && UtilValidate.isNotEmpty(SeoConfigUtil.getCategoryUrlSuffix())) {
urlBuilder.append(SeoConfigUtil.getCategoryUrlSuffix());
}
return urlBuilder.toString();
}
/**
* This is used when building category url in services.
*
* @param delegator
* @param wrapper
* @param prefix
* @param productCategoryId
* @param previousCategoryId
* @param productId
* @param viewSize
* @param viewIndex
* @param viewSort
* @param searchString
* @return
*/
public static String makeCategoryUrl(Delegator delegator, CategoryContentWrapper wrapper, String prefix,
String currentCategoryId, String previousCategoryId, String productId, String viewSize, String viewIndex,
String viewSort, String searchString) {
StringBuilder urlBuilder = new StringBuilder();
urlBuilder.append(prefix);
if (urlBuilder.charAt(urlBuilder.length() - 1) != '/') {
urlBuilder.append("/");
}
urlBuilder.append(CatalogUrlServlet.CATEGORY_REQUEST + "/");
if (UtilValidate.isNotEmpty(currentCategoryId)) {
List<String> trail = null;
trail = CategoryWorker.adjustTrail(trail, currentCategoryId, previousCategoryId);
if (trail != null && trail.size() > 1) {
String lastCategoryId = trail.get(trail.size() - 1);
if (!"TOP".equals(lastCategoryId)) {
String categoryName = CatalogUrlSeoTransform.getCategoryIdNameMap().get(lastCategoryId);
if (UtilValidate.isNotEmpty(categoryName)) {
urlBuilder.append(categoryName);
urlBuilder.append(URL_HYPHEN);
urlBuilder.append(lastCategoryId.trim().replaceAll(" ", URL_HYPHEN));
} else {
urlBuilder.append(lastCategoryId.trim().replaceAll(" ", URL_HYPHEN));
}
}
}
}
if (!urlBuilder.toString().endsWith("/") && UtilValidate.isNotEmpty(SeoConfigUtil.getCategoryUrlSuffix())) {
urlBuilder.append(SeoConfigUtil.getCategoryUrlSuffix());
}
// append view index
if (UtilValidate.isNotEmpty(viewIndex)) {
if (!urlBuilder.toString().endsWith("?") && !urlBuilder.toString().endsWith("&")) {
urlBuilder.append("?");
}
urlBuilder.append("viewIndex=" + viewIndex + "&");
}
// append view size
if (UtilValidate.isNotEmpty(viewSize)) {
if (!urlBuilder.toString().endsWith("?") && !urlBuilder.toString().endsWith("&")) {
urlBuilder.append("?");
}
urlBuilder.append("viewSize=" + viewSize + "&");
}
// append view sort
if (UtilValidate.isNotEmpty(viewSort)) {
if (!urlBuilder.toString().endsWith("?") && !urlBuilder.toString().endsWith("&")) {
urlBuilder.append("?");
}
urlBuilder.append("viewSort=" + viewSort + "&");
}
// append search string
if (UtilValidate.isNotEmpty(searchString)) {
if (!urlBuilder.toString().endsWith("?") && !urlBuilder.toString().endsWith("&")) {
urlBuilder.append("?");
}
urlBuilder.append("searchString=" + searchString + "&");
}
if (urlBuilder.toString().endsWith("&")) {
return urlBuilder.toString().substring(0, urlBuilder.toString().length()-1);
}
return urlBuilder.toString();
}
}