Added: 
ofbiz/branches/OFBIZ-5312-ofbiz-ecommerce-seo-2013-10-23/applications/product/src/org/ofbiz/product/category/ftl/UrlRegexpTransform.java
URL: 
http://svn.apache.org/viewvc/ofbiz/branches/OFBIZ-5312-ofbiz-ecommerce-seo-2013-10-23/applications/product/src/org/ofbiz/product/category/ftl/UrlRegexpTransform.java?rev=1535171&view=auto
==============================================================================
--- 
ofbiz/branches/OFBIZ-5312-ofbiz-ecommerce-seo-2013-10-23/applications/product/src/org/ofbiz/product/category/ftl/UrlRegexpTransform.java
 (added)
+++ 
ofbiz/branches/OFBIZ-5312-ofbiz-ecommerce-seo-2013-10-23/applications/product/src/org/ofbiz/product/category/ftl/UrlRegexpTransform.java
 Wed Oct 23 20:48:36 2013
@@ -0,0 +1,231 @@
+/*******************************************************************************
+ * 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.Iterator;
+import java.util.Map;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.apache.oro.text.regex.Pattern;
+import org.apache.oro.text.regex.Perl5Matcher;
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.entity.GenericValue;
+import org.ofbiz.product.category.UrlRegexpConfigUtil;
+import org.ofbiz.webapp.control.RequestHandler;
+
+import freemarker.core.Environment;
+import freemarker.ext.beans.BeanModel;
+import freemarker.template.SimpleScalar;
+import freemarker.template.TemplateScalarModel;
+import freemarker.template.TemplateTransformModel;
+
+/**
+ * UrlRegexpTransform - Freemarker Transform for Products URLs (links)
+ * 
+ */
+public class UrlRegexpTransform implements TemplateTransformModel {
+
+    private static final String module = UrlRegexpTransform.class.getName();
+
+    public boolean checkArg(Map args, String key, boolean defaultValue) {
+        if (!args.containsKey(key)) {
+            return defaultValue;
+        } else {
+            Object o = args.get(key);
+            if (o instanceof SimpleScalar) {
+                SimpleScalar s = (SimpleScalar) o;
+                return "true".equalsIgnoreCase(s.getAsString());
+            }
+            return defaultValue;
+        }
+    }
+
+    public Writer getWriter(final Writer out, Map args) {
+        final StringBuffer buf = new StringBuffer();
+        final boolean fullPath = checkArg(args, "fullPath", false);
+        final boolean secure = checkArg(args, "secure", false);
+        final boolean encode = checkArg(args, "encode", true);
+
+        return new Writer(out) {
+
+            public void write(char cbuf[], int off, int len) {
+                buf.append(cbuf, off, len);
+            }
+
+            public void flush() throws IOException {
+                out.flush();
+            }
+
+            public void close() throws IOException {
+                try {
+                    Environment env = Environment.getCurrentEnvironment();
+                    BeanModel req = (BeanModel) env.getVariable("request");
+                    BeanModel res = (BeanModel) env.getVariable("response");
+                    Object prefix = env.getVariable("urlPrefix");
+                    if (req != null) {
+                        HttpServletRequest request = (HttpServletRequest) 
req.getWrappedObject();
+                        ServletContext ctx = (ServletContext) 
request.getAttribute("servletContext");
+                        HttpServletResponse response = null;
+                        if (res != null) {
+                            response = (HttpServletResponse) 
res.getWrappedObject();
+                        }
+                        HttpSession session = request.getSession();
+                        GenericValue userLogin = (GenericValue) 
session.getAttribute("userLogin");
+
+                        // anonymous shoppers are not logged in
+                        if (userLogin != null && 
"anonymous".equals(userLogin.getString("userLoginId"))) {
+                            userLogin = null;
+                        }
+
+                        RequestHandler rh = (RequestHandler) 
ctx.getAttribute("_REQUEST_HANDLER_");
+                        out.write(seoUrl(rh.makeLink(request, response, 
buf.toString(), fullPath, secure, encode), userLogin == null));
+                    } else if (prefix != null) {
+                        if (prefix instanceof TemplateScalarModel) {
+                            TemplateScalarModel s = (TemplateScalarModel) 
prefix;
+                            String prefixString = s.getAsString();
+                            String bufString = buf.toString();
+                            boolean prefixSlash = prefixString.endsWith("/");
+                            boolean bufSlash = bufString.startsWith("/");
+                            if (prefixSlash && bufSlash) {
+                                bufString = bufString.substring(1);
+                            } else if (!prefixSlash && !bufSlash) {
+                                bufString = "/" + bufString;
+                            }
+                            out.write(prefixString + bufString);
+                        }
+                    } else {
+                        out.write(buf.toString());
+                    }
+                } catch (Exception e) {
+                    throw new IOException(e.getMessage());
+                }
+            }
+        };
+    }
+
+    /**
+     * Transform a url according to seo pattern regular expressions.
+     * 
+     * @param url
+     *            , String to do the seo transform
+     * @param isAnon
+     *            , boolean to indicate whether it's an anonymous visit.
+     * 
+     * @return String, the transformed url.
+     */
+    public static String seoUrl(String url, boolean isAnon) {
+        Perl5Matcher matcher = new Perl5Matcher();
+        if (UrlRegexpConfigUtil.checkUseUrlRegexp() && matcher.matches(url, 
UrlRegexpConfigUtil.getGeneralRegexpPattern())) {
+            Iterator<String> keys = 
UrlRegexpConfigUtil.getSeoPatterns().keySet().iterator();
+            boolean foundMatch = false;
+            while (keys.hasNext()) {
+                String key = keys.next();
+                Pattern pattern = 
UrlRegexpConfigUtil.getSeoPatterns().get(key);
+                if (pattern.getPattern().contains(";jsessionid=")) {
+                    if (isAnon) {
+                        if (UrlRegexpConfigUtil.isJSessionIdAnonEnabled()) {
+                            continue;
+                        }
+                    } else {
+                        if (UrlRegexpConfigUtil.isJSessionIdUserEnabled()) {
+                            continue;
+                        } else {
+                            boolean foundException = false;
+                            for (int i = 0; i < 
UrlRegexpConfigUtil.getUserExceptionPatterns().size(); i++) {
+                                if (matcher.matches(url, 
UrlRegexpConfigUtil.getUserExceptionPatterns().get(i))) {
+                                    foundException = true;
+                                    break;
+                                }
+                            }
+                            if (foundException) {
+                                continue;
+                            }
+                        }
+                    }
+                }
+                String replacement = 
UrlRegexpConfigUtil.getSeoReplacements().get(key);
+                if (matcher.matches(url, pattern)) {
+                    for (int i = 1; i < matcher.getMatch().groups(); i++) {
+                        replacement = replacement.replaceAll("\\$" + i, 
matcher.getMatch().group(i));
+                    }
+                    // break if found any matcher
+                    url = replacement;
+                    foundMatch = true;
+                    break;
+                }
+            }
+            if (!foundMatch && UrlRegexpConfigUtil.isDebugEnabled()) {
+                Debug.logInfo("Can NOT find a seo transform pattern for this 
url: " + url, module);
+            }
+        }
+        return url;
+    }
+
+    static {
+        UrlRegexpConfigUtil.init();
+    }
+
+    /**
+     * Forward a uri according to forward pattern regular expressions. Note: 
this is developed for Filter usage.
+     * 
+     * @param uri
+     *            String to reverse transform
+     * @return String
+     */
+    public static boolean forwardUri(HttpServletResponse response, String uri) 
{
+        Perl5Matcher matcher = new Perl5Matcher();
+        boolean foundMatch = false;
+        Integer responseCodeInt = null;
+        if (UrlRegexpConfigUtil.checkUseUrlRegexp() && 
UrlRegexpConfigUtil.getForwardPatterns() != null && 
UrlRegexpConfigUtil.getForwardReplacements() != null) {
+            Iterator<String> keys = 
UrlRegexpConfigUtil.getForwardPatterns().keySet().iterator();
+            while (keys.hasNext()) {
+                String key = keys.next();
+                Pattern pattern = 
UrlRegexpConfigUtil.getForwardPatterns().get(key);
+                String replacement = 
UrlRegexpConfigUtil.getForwardReplacements().get(key);
+                if (matcher.matches(uri, pattern)) {
+                    for (int i = 1; i < matcher.getMatch().groups(); i++) {
+                        replacement = replacement.replaceAll("\\$" + i, 
matcher.getMatch().group(i));
+                    }
+                    // break if found any matcher
+                    uri = replacement;
+                    responseCodeInt = 
UrlRegexpConfigUtil.getForwardResponseCodes().get(key);
+                    foundMatch = true;
+                    break;
+                }
+            }
+        }
+        if (foundMatch) {
+            if (responseCodeInt == null) {
+                response.setStatus(UrlRegexpConfigUtil.DEFAULT_RESPONSECODE);
+            } else {
+                response.setStatus(responseCodeInt.intValue());
+            }
+            response.setHeader("Location", uri);
+        } else if (UrlRegexpConfigUtil.isDebugEnabled()) {
+            Debug.logInfo("Can NOT forward this url: " + uri, module);
+        }
+        return foundMatch;
+    }
+}

Propchange: 
ofbiz/branches/OFBIZ-5312-ofbiz-ecommerce-seo-2013-10-23/applications/product/src/org/ofbiz/product/category/ftl/UrlRegexpTransform.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
ofbiz/branches/OFBIZ-5312-ofbiz-ecommerce-seo-2013-10-23/applications/product/src/org/ofbiz/product/category/ftl/UrlRegexpTransform.java
------------------------------------------------------------------------------
    svn:keywords = Date Rev Author URL Id

Propchange: 
ofbiz/branches/OFBIZ-5312-ofbiz-ecommerce-seo-2013-10-23/applications/product/src/org/ofbiz/product/category/ftl/UrlRegexpTransform.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: 
ofbiz/branches/OFBIZ-5312-ofbiz-ecommerce-seo-2013-10-23/framework/webapp/src/org/ofbiz/webapp/control/RequestHandler.java
URL: 
http://svn.apache.org/viewvc/ofbiz/branches/OFBIZ-5312-ofbiz-ecommerce-seo-2013-10-23/framework/webapp/src/org/ofbiz/webapp/control/RequestHandler.java?rev=1535171&r1=1535157&r2=1535171&view=diff
==============================================================================
--- 
ofbiz/branches/OFBIZ-5312-ofbiz-ecommerce-seo-2013-10-23/framework/webapp/src/org/ofbiz/webapp/control/RequestHandler.java
 (original)
+++ 
ofbiz/branches/OFBIZ-5312-ofbiz-ecommerce-seo-2013-10-23/framework/webapp/src/org/ofbiz/webapp/control/RequestHandler.java
 Wed Oct 23 20:48:36 2013
@@ -58,6 +58,7 @@ import org.ofbiz.webapp.stats.ServerHitB
 import org.ofbiz.webapp.view.ViewFactory;
 import org.ofbiz.webapp.view.ViewHandler;
 import org.ofbiz.webapp.view.ViewHandlerException;
+import org.ofbiz.webapp.website.WebSiteProperties;
 import org.ofbiz.webapp.website.WebSiteWorker;
 import org.owasp.esapi.errors.EncodingException;
 
@@ -857,7 +858,7 @@ public class RequestHandler {
     }
     private void renderView(String view, boolean allowExtView, 
HttpServletRequest req, HttpServletResponse resp, String saveName) throws 
RequestHandlerException {
         GenericValue userLogin = (GenericValue) 
req.getSession().getAttribute("userLogin");
-        // workaraound if we are in the root webapp
+        // workaround if we are in the root webapp
         String cname = UtilHttp.getApplicationName(req);
         String oldView = view;
 
@@ -868,7 +869,10 @@ public class RequestHandler {
         // if the view name starts with the control servlet name and a /, then 
it was an
         // attempt to override the default view with a call back into the 
control servlet,
         // so just get the target view name and use that
-        String servletName = req.getServletPath().substring(1);
+        String servletName = req.getServletPath();
+        if (UtilValidate.isNotEmpty(servletName) && servletName.length() > 1) {
+            servletName = servletName.substring(1);
+        }
 
         if (Debug.infoOn()) Debug.logInfo("Rendering View [" + view + "], 
sessionId=" + UtilHttp.getSessionId(req), module);
         if (view.startsWith(servletName + "/")) {

Modified: 
ofbiz/branches/OFBIZ-5312-ofbiz-ecommerce-seo-2013-10-23/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/web.xml
URL: 
http://svn.apache.org/viewvc/ofbiz/branches/OFBIZ-5312-ofbiz-ecommerce-seo-2013-10-23/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/web.xml?rev=1535171&r1=1535157&r2=1535171&view=diff
==============================================================================
--- 
ofbiz/branches/OFBIZ-5312-ofbiz-ecommerce-seo-2013-10-23/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/web.xml
 (original)
+++ 
ofbiz/branches/OFBIZ-5312-ofbiz-ecommerce-seo-2013-10-23/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/web.xml
 Wed Oct 23 20:48:36 2013
@@ -52,17 +52,23 @@ under the License.
             frequently switch between http and https.
         </description>
     </context-param>
+    <context-param>
+        <param-name>defaultPage</param-name>
+        <param-value>/main</param-value>
+        <description>Default page uri. Important: please DO add or remove 
/control to match url-pattern of SeoControlServlet.
+        </description>
+    </context-param>
 
     <filter>
-        <filter-name>CatalogUrlFilter</filter-name>
-        <display-name>CatalogUrlFilter</display-name>
-        
<filter-class>org.ofbiz.product.category.CatalogUrlFilter</filter-class>
+        <filter-name>SeoCatalogUrlFilter</filter-name>
+        <display-name>SeoCatalogUrlFilter</display-name>
+        
<filter-class>org.ofbiz.product.category.SeoCatalogUrlFilter</filter-class>
         
<init-param><param-name>defaultLocaleString</param-name><param-value>en_US</param-value></init-param>
     </filter>
     <filter>
-        <filter-name>ContentUrlFilter</filter-name>
-        <display-name>ContentUrlFilter</display-name>
-        <filter-class>org.ofbiz.content.content.ContentUrlFilter</filter-class>
+        <filter-name>SeoContentUrlFilter</filter-name>
+        <display-name>SeoContentUrlFilter</display-name>
+        
<filter-class>org.ofbiz.product.category.SeoContentUrlFilter</filter-class>
         <init-param>
             <param-name>defaultLocaleString</param-name>
             <param-value>en_US</param-value>
@@ -70,9 +76,9 @@ under the License.
         
<init-param><param-name>viewRequest</param-name><param-value>ViewBlogArticle</param-value></init-param>
     </filter>
     <filter>
-        <filter-name>ContextFilter</filter-name>
-        <display-name>ContextFilter</display-name>
-        <filter-class>org.ofbiz.webapp.control.ContextFilter</filter-class>
+        <filter-name>SeoContextFilter</filter-name>
+        <display-name>SeoContextFilter</display-name>
+        
<filter-class>org.ofbiz.product.category.SeoContextFilter</filter-class>
         <init-param>
             <param-name>disableContextSecurity</param-name>
             <param-value>N</param-value>
@@ -83,15 +89,15 @@ under the License.
         </init-param>
     </filter>
     <filter-mapping>
-        <filter-name>CatalogUrlFilter</filter-name>
+        <filter-name>SeoCatalogUrlFilter</filter-name>
         <url-pattern>/*</url-pattern>
     </filter-mapping>
     <filter-mapping>
-        <filter-name>ContentUrlFilter</filter-name>
+        <filter-name>SeoContentUrlFilter</filter-name>
         <url-pattern>/*</url-pattern>
     </filter-mapping>
     <filter-mapping>
-        <filter-name>ContextFilter</filter-name>
+        <filter-name>SeoContextFilter</filter-name>
         <url-pattern>/*</url-pattern>
     </filter-mapping>
 
@@ -105,10 +111,10 @@ under the License.
     
<listener><listener-class>org.ofbiz.webapp.control.LoginEventListener</listener-class></listener>
 
     <servlet>
-        <servlet-name>ControlServlet</servlet-name>
-        <display-name>ControlServlet</display-name>
-        <description>Main Control Servlet</description>
-        <servlet-class>org.ofbiz.webapp.control.ControlServlet</servlet-class>
+        <servlet-name>SeoControlServlet</servlet-name>
+        <display-name>SeoControlServlet</display-name>
+        <description>Main SEO Control Servlet</description>
+        
<servlet-class>org.ofbiz.product.category.SeoControlServlet</servlet-class>
         <load-on-startup>1</load-on-startup>
     </servlet>
     <!-- un-comment for Worldpay
@@ -121,16 +127,16 @@ under the License.
     </servlet>
     -->
     <servlet>
-        <servlet-name>CatalogUrlServlet</servlet-name>
-        <display-name>CatalogUrlServlet</display-name>
-        <description>Catalog (Category/Product) URL Servlet</description>
-        
<servlet-class>org.ofbiz.product.category.CatalogUrlServlet</servlet-class>
+        <servlet-name>SeoCatalogUrlServlet</servlet-name>
+        <display-name>SeoCatalogUrlServlet</display-name>
+        <description>SEO Catalog (Category/Product) URL Servlet</description>
+        
<servlet-class>org.ofbiz.product.category.SeoCatalogUrlServlet</servlet-class>
         <load-on-startup>1</load-on-startup>
     </servlet>
 
     <servlet-mapping>
-        <servlet-name>ControlServlet</servlet-name>
-        <url-pattern>/control/*</url-pattern>
+        <servlet-name>SeoControlServlet</servlet-name>
+        <url-pattern>/*</url-pattern>
     </servlet-mapping>
     <!-- un-comment for Worldpay
     <servlet-mapping>
@@ -139,7 +145,7 @@ under the License.
     </servlet-mapping>
     -->
     <servlet-mapping>
-        <servlet-name>CatalogUrlServlet</servlet-name>
+        <servlet-name>SeoCatalogUrlServlet</servlet-name>
         <url-pattern>/products/*</url-pattern>
     </servlet-mapping>
 


Reply via email to